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.
This commit is contained in:
parent
79593b0dec
commit
86fd39f354
|
@ -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
|
||||
|
@ -1128,6 +1129,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,
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -48,21 +48,18 @@ typedef struct {
|
|||
static inline kthread_t *
|
||||
mutex_owner(kmutex_t *mp)
|
||||
{
|
||||
struct thread_info *owner;
|
||||
#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;
|
||||
|
||||
owner = ACCESS_ONCE(mp->m.owner);
|
||||
if (owner)
|
||||
return owner->task;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue