diff options
author | Chunwei Chen <[email protected]> | 2016-05-25 16:35:42 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2016-05-31 11:44:15 -0700 |
commit | f58040c0fc8bc6490fcc75db7fc3e709dfc3c656 (patch) | |
tree | 03aaebb8e0e152ade6edb7a9ae14f4b430314797 /config | |
parent | c60a51b640bab61c54f370752750841675730899 (diff) |
Implement a proper rw_tryupgrade
Current rw_tryupgrade does rw_exit and then rw_tryenter(RW_RWITER), and then
does rw_enter(RW_READER) if it fails. This violate the assumption that
rw_tryupgrade should be atomic and could cause extra contention or even lock
inversion.
This patch we implement a proper rw_tryupgrade. For rwsem-spinlock, we take
the spinlock to check rwsem->count and rwsem->wait_list. For normal rwsem, we
use cmpxchg on rwsem->count to change the value from single reader to single
writer.
Signed-off-by: Chunwei Chen <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Tim Chase <[email protected]>
Closes zfsonlinux/zfs#4692
Closes #554
Diffstat (limited to 'config')
-rw-r--r-- | config/spl-build.m4 | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/config/spl-build.m4 b/config/spl-build.m4 index 720506959..d705c6531 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -39,6 +39,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE SPL_AC_SHRINK_CONTROL_STRUCT SPL_AC_RWSEM_SPINLOCK_IS_RAW + SPL_AC_RWSEM_ACTIVITY SPL_AC_SCHED_RT_HEADER SPL_AC_2ARGS_VFS_GETATTR SPL_AC_USLEEP_RANGE @@ -1317,6 +1318,30 @@ AC_DEFUN([SPL_AC_RWSEM_SPINLOCK_IS_RAW], [ ]) dnl # +dnl # 3.16 API Change +dnl # +dnl # rwsem-spinlock "->activity" changed to "->count" +dnl # +AC_DEFUN([SPL_AC_RWSEM_ACTIVITY], [ + AC_MSG_CHECKING([whether struct rw_semaphore has member activity]) + tmp_flags="$EXTRA_KCFLAGS" + EXTRA_KCFLAGS="-Werror" + SPL_LINUX_TRY_COMPILE([ + #include <linux/rwsem.h> + ],[ + struct rw_semaphore dummy_semaphore __attribute__ ((unused)); + dummy_semaphore.activity = 0; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_RWSEM_ACTIVITY, 1, + [struct rw_semaphore has member activity]) + ],[ + AC_MSG_RESULT(no) + ]) + EXTRA_KCFLAGS="$tmp_flags" +]) + +dnl # dnl # 3.9 API change, dnl # Moved things from linux/sched.h to linux/sched/rt.h dnl # |