diff --git a/config/spl-build.m4 b/config/spl-build.m4 index d2cb68b6b..4b55809ce 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -25,8 +25,6 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_SHRINKER_CALLBACK SPL_AC_CTL_NAME SPL_AC_PDE_DATA - SPL_AC_MUTEX_OWNER - SPL_AC_MUTEX_OWNER_TASK_STRUCT SPL_AC_SET_FS_PWD_WITH_CONST SPL_AC_2ARGS_VFS_UNLINK SPL_AC_4ARGS_VFS_RENAME @@ -865,54 +863,6 @@ AC_DEFUN([SPL_AC_CTL_NAME], [ ]) ]) -dnl # -dnl # 2.6.29 API change, -dnl # Adaptive mutexs were introduced which track the mutex owner. The -dnl # mutex wrappers leverage this functionality to avoid tracking the -dnl # owner multipe times. -dnl # -AC_DEFUN([SPL_AC_MUTEX_OWNER], [ - AC_MSG_CHECKING([whether struct mutex has owner]) - SPL_LINUX_TRY_COMPILE([ - #include - ],[ - struct mutex mtx __attribute__ ((unused)); - mtx.owner = NULL; - ],[ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_MUTEX_OWNER, 1, [struct mutex has owner]) - ],[ - AC_MSG_RESULT(no) - ]) -]) - -dnl # -dnl # 2.6.39 API change, -dnl # Owner type change. A Linux mutex prior to 2.6.39 would store -dnl # the owner as a thread_info pointer when CONFIG_DEBUG_MUTEXES -dnl # was defined. As of 2.6.39 this was changed to a task_struct -dnl # pointer which frankly makes a lot more sense. -dnl # -AC_DEFUN([SPL_AC_MUTEX_OWNER_TASK_STRUCT], [ - AC_MSG_CHECKING([whether struct mutex owner is a task_struct]) - tmp_flags="$EXTRA_KCFLAGS" - EXTRA_KCFLAGS="-Werror" - SPL_LINUX_TRY_COMPILE([ - #include - #include - ],[ - struct mutex mtx __attribute__ ((unused)); - mtx.owner = current; - ],[ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_MUTEX_OWNER_TASK_STRUCT, 1, - [struct mutex owner is a task_struct]) - ],[ - AC_MSG_RESULT(no) - ]) - EXTRA_KCFLAGS="$tmp_flags" -]) - dnl # dnl # 3.10 API change, dnl # PDE is replaced by PDE_DATA diff --git a/include/sys/mutex.h b/include/sys/mutex.h index 43467223c..2e4509345 100644 --- a/include/sys/mutex.h +++ b/include/sys/mutex.h @@ -35,81 +35,6 @@ typedef enum { MUTEX_ADAPTIVE = 2 } kmutex_type_t; -#if defined(HAVE_MUTEX_OWNER) && defined(CONFIG_SMP) && \ - !defined(CONFIG_DEBUG_MUTEXES) - -typedef struct { - struct mutex m; - spinlock_t m_lock; /* used for serializing mutex_exit */ -} kmutex_t; - -static inline kthread_t * -mutex_owner(kmutex_t *mp) -{ -#if defined(HAVE_MUTEX_OWNER_TASK_STRUCT) - return (ACCESS_ONCE(mp->m.owner)); -#else - struct thread_info *owner = ACCESS_ONCE(mp->m.owner); - if (owner) - return (owner->task); - - return (NULL); -#endif -} - -#define mutex_owned(mp) (mutex_owner(mp) == current) -#define MUTEX_HELD(mp) mutex_owned(mp) -#define MUTEX_NOT_HELD(mp) (!MUTEX_HELD(mp)) -#undef mutex_init -#define mutex_init(mp, name, type, ibc) \ -{ \ - static struct lock_class_key __key; \ - ASSERT(type == MUTEX_DEFAULT); \ - \ - __mutex_init(&(mp)->m, #mp, &__key); \ - spin_lock_init(&(mp)->m_lock); \ -} - -#undef mutex_destroy -#define mutex_destroy(mp) \ -{ \ - VERIFY3P(mutex_owner(mp), ==, NULL); \ -} - -#define mutex_tryenter(mp) mutex_trylock(&(mp)->m) -#define mutex_enter(mp) \ -{ \ - ASSERT3P(mutex_owner(mp), !=, current); \ - mutex_lock(&(mp)->m); \ -} -/* - * The reason for the spinlock: - * - * The Linux mutex is designed with a fast-path/slow-path design such that it - * does not guarantee serialization upon itself, allowing a race where latter - * acquirers finish mutex_unlock before former ones. - * - * The race renders it unsafe to be used for serializing the freeing of an - * object in which the mutex is embedded, where the latter acquirer could go - * on to free the object while the former one is still doing mutex_unlock and - * causing memory corruption. - * - * However, there are many places in ZFS where the mutex is used for - * serializing object freeing, and the code is shared among other OSes without - * this issue. Thus, we need the spinlock to force the serialization on - * mutex_exit(). - * - * See http://lwn.net/Articles/575477/ for the information about the race. - */ -#define mutex_exit(mp) \ -{ \ - spin_lock(&(mp)->m_lock); \ - mutex_unlock(&(mp)->m); \ - spin_unlock(&(mp)->m_lock); \ -} - -#else /* HAVE_MUTEX_OWNER */ - typedef struct { struct mutex m_mutex; spinlock_t m_lock; /* used for serializing mutex_exit */ @@ -175,6 +100,25 @@ spl_mutex_clear_owner(kmutex_t *mp) spl_mutex_set_owner(mp); \ } +/* + * The reason for the spinlock: + * + * The Linux mutex is designed with a fast-path/slow-path design such that it + * does not guarantee serialization upon itself, allowing a race where latter + * acquirers finish mutex_unlock before former ones. + * + * The race renders it unsafe to be used for serializing the freeing of an + * object in which the mutex is embedded, where the latter acquirer could go + * on to free the object while the former one is still doing mutex_unlock and + * causing memory corruption. + * + * However, there are many places in ZFS where the mutex is used for + * serializing object freeing, and the code is shared among other OSes without + * this issue. Thus, we need the spinlock to force the serialization on + * mutex_exit(). + * + * See http://lwn.net/Articles/575477/ for the information about the race. + */ #define mutex_exit(mp) \ { \ spin_lock(&(mp)->m_lock); \ @@ -183,8 +127,6 @@ spl_mutex_clear_owner(kmutex_t *mp) spin_unlock(&(mp)->m_lock); \ } -#endif /* HAVE_MUTEX_OWNER */ - int spl_mutex_init(void); void spl_mutex_fini(void);