summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2011-06-24 11:57:14 -0700
committerBrian Behlendorf <[email protected]>2011-06-24 13:00:08 -0700
commit86fd39f354778eb10e77a7c1660b59ca16ffcc16 (patch)
treeddba0bbdcc45babd1863a732c96bc475a19251a7
parent79593b0dec57ee94c5bb56cdc2770ebde81ecea9 (diff)
Linux 2.6.39 compat, mutex owner
Prior to Linux 2.6.39 when CONFIG_DEBUG_MUTEXES was defined the kernel stored a thread_info pointer as the mutex owner. From this you could get the pointer of the current task_struct to compare with get_current(). As of Linux 2.6.39 this behavior has changed and now the mutex stores a pointer to the task_struct. This commit detects the type of pointer stored in the mutex and adjusts the mutex_owner() and mutex_owned() functions to perform the correct comparision.
-rw-r--r--config/spl-build.m427
-rwxr-xr-xconfigure138
-rw-r--r--include/sys/mutex.h21
-rw-r--r--spl_config.h.in3
4 files changed, 177 insertions, 12 deletions
diff --git a/config/spl-build.m4 b/config/spl-build.m4
index 75267bb83..ea5078507 100644
--- a/config/spl-build.m4
+++ b/config/spl-build.m4
@@ -48,6 +48,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
SPL_AC_MONOTONIC_CLOCK
SPL_AC_INODE_I_MUTEX
SPL_AC_MUTEX_OWNER
+ SPL_AC_MUTEX_OWNER_TASK_STRUCT
SPL_AC_MUTEX_LOCK_NESTED
SPL_AC_3ARGS_ON_EACH_CPU
SPL_AC_KALLSYMS_LOOKUP_NAME
@@ -1129,6 +1130,32 @@ AC_DEFUN([SPL_AC_MUTEX_OWNER], [
])
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>
+ ],[
+ 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 # 2.6.18 API change,
dnl # First introduced 'mutex_lock_nested()' in include/linux/mutex.h,
dnl # as part of the mutex validator. Fallback to using 'mutex_lock()'
diff --git a/configure b/configure
index c537b9817..cf396e484 100755
--- a/configure
+++ b/configure
@@ -13687,6 +13687,75 @@ fi
+ { $as_echo "$as_me:$LINENO: checking whether struct mutex owner is a task_struct" >&5
+$as_echo_n "checking whether struct mutex owner is a task_struct... " >&6; }
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+
+ #include <linux/mutex.h>
+
+int
+main (void)
+{
+
+ struct mutex mtx __attribute__ ((unused));
+ mtx.owner = current;
+
+ ;
+ return 0;
+}
+
+_ACEOF
+
+
+ rm -Rf build && mkdir -p build
+ echo "obj-m := conftest.o" >build/Makefile
+ if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MUTEX_OWNER_TASK_STRUCT 1
+_ACEOF
+
+
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+
+ rm -Rf build
+
+
+ EXTRA_KCFLAGS="$tmp_flags"
+
+
{ $as_echo "$as_me:$LINENO: checking whether mutex_lock_nested() is available" >&5
$as_echo_n "checking whether mutex_lock_nested() is available... " >&6; }
@@ -17818,6 +17887,75 @@ fi
+ { $as_echo "$as_me:$LINENO: checking whether struct mutex owner is a task_struct" >&5
+$as_echo_n "checking whether struct mutex owner is a task_struct... " >&6; }
+ tmp_flags="$EXTRA_KCFLAGS"
+ EXTRA_KCFLAGS="-Werror"
+
+
+cat confdefs.h - <<_ACEOF >conftest.c
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+
+ #include <linux/mutex.h>
+
+int
+main (void)
+{
+
+ struct mutex mtx __attribute__ ((unused));
+ mtx.owner = current;
+
+ ;
+ return 0;
+}
+
+_ACEOF
+
+
+ rm -Rf build && mkdir -p build
+ echo "obj-m := conftest.o" >build/Makefile
+ if { ac_try='cp conftest.c build && make modules -C $LINUX_OBJ EXTRA_CFLAGS="-Werror-implicit-function-declaration $EXTRA_KCFLAGS" $ARCH_UM M=$PWD/build'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } >/dev/null && { ac_try='test -s build/conftest.o'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+
+ { $as_echo "$as_me:$LINENO: result: yes" >&5
+$as_echo "yes" >&6; }
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_MUTEX_OWNER_TASK_STRUCT 1
+_ACEOF
+
+
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+
+
+
+fi
+
+ rm -Rf build
+
+
+ EXTRA_KCFLAGS="$tmp_flags"
+
+
{ $as_echo "$as_me:$LINENO: checking whether mutex_lock_nested() is available" >&5
$as_echo_n "checking whether mutex_lock_nested() is available... " >&6; }
diff --git a/include/sys/mutex.h b/include/sys/mutex.h
index ebf9151f1..659214f50 100644
--- a/include/sys/mutex.h
+++ b/include/sys/mutex.h
@@ -48,21 +48,18 @@ typedef struct {
static inline kthread_t *
mutex_owner(kmutex_t *mp)
{
- struct thread_info *owner;
-
- owner = ACCESS_ONCE(mp->m.owner);
- if (owner)
- return owner->task;
-
- return NULL;
-}
+#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;
-static inline int
-mutex_owned(kmutex_t *mp)
-{
- return (ACCESS_ONCE(mp->m.owner) == current_thread_info());
+ 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
diff --git a/spl_config.h.in b/spl_config.h.in
index 95394e6e2..97f0e06f3 100644
--- a/spl_config.h.in
+++ b/spl_config.h.in
@@ -135,6 +135,9 @@
/* struct mutex has owner */
#undef HAVE_MUTEX_OWNER
+/* struct mutex owner is a task_struct */
+#undef HAVE_MUTEX_OWNER_TASK_STRUCT
+
/* next_online_pgdat() is available */
#undef HAVE_NEXT_ONLINE_PGDAT