]> git.proxmox.com Git - mirror_spl.git/commitdiff
Make kmutex_t typesafe in all cases.
authorRicardo M. Correia <ricardo.correia@oracle.com>
Mon, 22 Nov 2010 08:20:58 +0000 (00:20 -0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 29 Nov 2010 19:25:32 +0000 (11:25 -0800)
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>
include/sys/mutex.h

index 1a8b2581343c48783fd696a7eb012ec3f8f78c4d..ebf9151f16615fdcc7906039f0ad7edaf521e56f 100644 (file)
@@ -37,14 +37,20 @@ typedef enum {
 
 #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 *
 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)
                 return owner->task;
 
@@ -54,7 +60,7 @@ mutex_owner(kmutex_t *mp)
 static inline int
 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)
@@ -65,31 +71,31 @@ mutex_owned(kmutex_t *mp)
         static struct lock_class_key __key;                             \
         ASSERT(type == MUTEX_DEFAULT);                                  \
                                                                         \
-        __mutex_init((mp), #mp, &__key);                                \
+        __mutex_init(&(mp)->m, #mp, &__key);                            \
 })
 
 #undef mutex_destroy
 #define mutex_destroy(mp)                                               \
 ({                                                                      \
-       VERIFY3P(mutex_owner(mp), ==, NULL);                            \
+        VERIFY3P(mutex_owner(mp), ==, NULL);                            \
 })
 
-#define mutex_tryenter(mp)              mutex_trylock(mp)
-#define mutex_enter(mp)                 mutex_lock(mp)
+#define mutex_tryenter(mp)              mutex_trylock(&(mp)->m)
+#define mutex_enter(mp)                 mutex_lock(&(mp)->m)
 
 /* mutex->owner is not cleared when CONFIG_DEBUG_MUTEXES is set */
 #ifdef CONFIG_DEBUG_MUTEXES
 # define mutex_exit(mp)                                                 \
 ({                                                                      \
-        mutex_unlock(mp);                                               \
-        (mp)->owner = NULL;                                             \
+        mutex_unlock(&(mp)->m);                                         \
+        (mp)->m.owner = NULL;                                           \
 })
 #else
-# define mutex_exit(mp)                 mutex_unlock(mp)
+# define mutex_exit(mp)                 mutex_unlock(&(mp)->m)
 #endif /* CONFIG_DEBUG_MUTEXES */
 
 #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
 # define mutex_enter_nested(mp, sc)     mutex_enter(mp)
 #endif /* HAVE_GPL_ONLY_SYMBOLS */
@@ -172,7 +178,7 @@ mutex_owner(kmutex_t *mp)
 #undef mutex_destroy
 #define mutex_destroy(mp)                                               \
 ({                                                                      \
-       VERIFY3P(mutex_owner(mp), ==, NULL);                            \
+        VERIFY3P(mutex_owner(mp), ==, NULL);                            \
 })
 
 #define mutex_tryenter(mp)                                              \