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
])
])
-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 <linux/mutex.h>
- ],[
- 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 <linux/mutex.h>
- #include <linux/sched.h>
- ],[
- 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
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 */
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); \
spin_unlock(&(mp)->m_lock); \
}
-#endif /* HAVE_MUTEX_OWNER */
-
int spl_mutex_init(void);
void spl_mutex_fini(void);