]> granicus.if.org Git - zfs/commitdiff
Fix race condition in mutex_exit()
authorGunnar Beutner <gunnar@beutner.name>
Tue, 18 Oct 2011 00:32:50 +0000 (02:32 +0200)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Wed, 19 Oct 2011 16:58:41 +0000 (09:58 -0700)
On kernels with CONFIG_DEBUG_MUTEXES mutex_exit() clears the mutex
owner after releasing the mutex. This would cause mutex_owner()
to return an incorrect owner if another thread managed to lock the
mutex before mutex_exit() had a chance to clear the owner.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes ZFS issue #167

include/sys/mutex.h

index 659214f508af56375d86a4584862dde3048476ee..c55104a417ac16acdcbbf58f81562fed86c207b9 100644 (file)
@@ -35,7 +35,7 @@ typedef enum {
         MUTEX_ADAPTIVE = 2
 } kmutex_type_t;
 
-#if defined(HAVE_MUTEX_OWNER) && defined(CONFIG_SMP)
+#if defined(HAVE_MUTEX_OWNER) && defined(CONFIG_SMP) && !defined(CONFIG_DEBUG_MUTEXES)
 
 /*
  * We define a 1-field struct rather than a straight typedef to enforce type
@@ -79,17 +79,7 @@ mutex_owner(kmutex_t *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)->m);                                         \
-        (mp)->m.owner = NULL;                                           \
-})
-#else
-# define mutex_exit(mp)                 mutex_unlock(&(mp)->m)
-#endif /* CONFIG_DEBUG_MUTEXES */
+#define mutex_exit(mp)                 mutex_unlock(&(mp)->m)
 
 #ifdef HAVE_GPL_ONLY_SYMBOLS
 # define mutex_enter_nested(mp, sc)     mutex_lock_nested(&(mp)->m, sc)