mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-01-13 19:50:25 +03:00
Make kmutex_t typesafe in all cases.
When HAVE_MUTEX_OWNER and CONFIG_SMP are defined, kmutex_t is just a typedef for struct mutex. This is generally OK but has the downside that it can make mistakes such as mutex_lock(&kmutex_var) to pass by unnoticed until someone compiles the code without HAVE_MUTEX_OWNER or CONFIG_SMP (in which case kmutex_t is a real struct). Note that the correct API to call should have been mutex_enter() rather than mutex_lock(). We prevent these kind of mistakes by making kmutex_t a real structure with only one field. This makes kmutex_t typesafe and it shouldn't have any impact on the generated assembly code. Signed-off-by: Ricardo M. Correia <ricardo.correia@oracle.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
This commit is contained in:
parent
058de03caa
commit
c2f997b0b3
@ -37,14 +37,20 @@ typedef enum {
|
|||||||
|
|
||||||
#if defined(HAVE_MUTEX_OWNER) && defined(CONFIG_SMP)
|
#if defined(HAVE_MUTEX_OWNER) && defined(CONFIG_SMP)
|
||||||
|
|
||||||
typedef struct mutex kmutex_t;
|
/*
|
||||||
|
* We define a 1-field struct rather than a straight typedef to enforce type
|
||||||
|
* safety.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
struct mutex m;
|
||||||
|
} kmutex_t;
|
||||||
|
|
||||||
static inline kthread_t *
|
static inline kthread_t *
|
||||||
mutex_owner(kmutex_t *mp)
|
mutex_owner(kmutex_t *mp)
|
||||||
{
|
{
|
||||||
struct thread_info *owner;
|
struct thread_info *owner;
|
||||||
|
|
||||||
owner = ACCESS_ONCE(mp->owner);
|
owner = ACCESS_ONCE(mp->m.owner);
|
||||||
if (owner)
|
if (owner)
|
||||||
return owner->task;
|
return owner->task;
|
||||||
|
|
||||||
@ -54,7 +60,7 @@ mutex_owner(kmutex_t *mp)
|
|||||||
static inline int
|
static inline int
|
||||||
mutex_owned(kmutex_t *mp)
|
mutex_owned(kmutex_t *mp)
|
||||||
{
|
{
|
||||||
return (ACCESS_ONCE(mp->owner) == current_thread_info());
|
return (ACCESS_ONCE(mp->m.owner) == current_thread_info());
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MUTEX_HELD(mp) mutex_owned(mp)
|
#define MUTEX_HELD(mp) mutex_owned(mp)
|
||||||
@ -65,31 +71,31 @@ mutex_owned(kmutex_t *mp)
|
|||||||
static struct lock_class_key __key; \
|
static struct lock_class_key __key; \
|
||||||
ASSERT(type == MUTEX_DEFAULT); \
|
ASSERT(type == MUTEX_DEFAULT); \
|
||||||
\
|
\
|
||||||
__mutex_init((mp), #mp, &__key); \
|
__mutex_init(&(mp)->m, #mp, &__key); \
|
||||||
})
|
})
|
||||||
|
|
||||||
#undef mutex_destroy
|
#undef mutex_destroy
|
||||||
#define mutex_destroy(mp) \
|
#define mutex_destroy(mp) \
|
||||||
({ \
|
({ \
|
||||||
VERIFY3P(mutex_owner(mp), ==, NULL); \
|
VERIFY3P(mutex_owner(mp), ==, NULL); \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define mutex_tryenter(mp) mutex_trylock(mp)
|
#define mutex_tryenter(mp) mutex_trylock(&(mp)->m)
|
||||||
#define mutex_enter(mp) mutex_lock(mp)
|
#define mutex_enter(mp) mutex_lock(&(mp)->m)
|
||||||
|
|
||||||
/* mutex->owner is not cleared when CONFIG_DEBUG_MUTEXES is set */
|
/* mutex->owner is not cleared when CONFIG_DEBUG_MUTEXES is set */
|
||||||
#ifdef CONFIG_DEBUG_MUTEXES
|
#ifdef CONFIG_DEBUG_MUTEXES
|
||||||
# define mutex_exit(mp) \
|
# define mutex_exit(mp) \
|
||||||
({ \
|
({ \
|
||||||
mutex_unlock(mp); \
|
mutex_unlock(&(mp)->m); \
|
||||||
(mp)->owner = NULL; \
|
(mp)->m.owner = NULL; \
|
||||||
})
|
})
|
||||||
#else
|
#else
|
||||||
# define mutex_exit(mp) mutex_unlock(mp)
|
# define mutex_exit(mp) mutex_unlock(&(mp)->m)
|
||||||
#endif /* CONFIG_DEBUG_MUTEXES */
|
#endif /* CONFIG_DEBUG_MUTEXES */
|
||||||
|
|
||||||
#ifdef HAVE_GPL_ONLY_SYMBOLS
|
#ifdef HAVE_GPL_ONLY_SYMBOLS
|
||||||
# define mutex_enter_nested(mp, sc) mutex_lock_nested(mp, sc)
|
# define mutex_enter_nested(mp, sc) mutex_lock_nested(&(mp)->m, sc)
|
||||||
#else
|
#else
|
||||||
# define mutex_enter_nested(mp, sc) mutex_enter(mp)
|
# define mutex_enter_nested(mp, sc) mutex_enter(mp)
|
||||||
#endif /* HAVE_GPL_ONLY_SYMBOLS */
|
#endif /* HAVE_GPL_ONLY_SYMBOLS */
|
||||||
@ -172,7 +178,7 @@ mutex_owner(kmutex_t *mp)
|
|||||||
#undef mutex_destroy
|
#undef mutex_destroy
|
||||||
#define mutex_destroy(mp) \
|
#define mutex_destroy(mp) \
|
||||||
({ \
|
({ \
|
||||||
VERIFY3P(mutex_owner(mp), ==, NULL); \
|
VERIFY3P(mutex_owner(mp), ==, NULL); \
|
||||||
})
|
})
|
||||||
|
|
||||||
#define mutex_tryenter(mp) \
|
#define mutex_tryenter(mp) \
|
||||||
|
Loading…
Reference in New Issue
Block a user