summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGunnar Beutner <[email protected]>2011-10-18 02:32:50 +0200
committerBrian Behlendorf <[email protected]>2011-10-19 09:58:41 -0700
commit3160d4f56bf35492e9c400094f8c1ff2066d4459 (patch)
tree2b8e0fdfe1842f1671244e12d9c79a42efbb9bae
parentf3989ed3223363330af014062caeeb1afbd0503f (diff)
Fix race condition in mutex_exit()
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 <[email protected]> Closes ZFS issue #167
-rw-r--r--include/sys/mutex.h14
1 files changed, 2 insertions, 12 deletions
diff --git a/include/sys/mutex.h b/include/sys/mutex.h
index 659214f50..c55104a41 100644
--- a/include/sys/mutex.h
+++ b/include/sys/mutex.h
@@ -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)