mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-04-06 17:49:11 +03:00
Linux 4.8 compat: rw_semaphore atomic_long_t count
For non-rwsem-spinlocks the "count" member was changed from a "long" to "atomic_long_t" type. A configure check has been added to detect this change along with new versions of the _rwsem_tryupgrade() function and RWSEM_COUNT() macro. See https://github.com/torvalds/linux/commit/8ee62b18 for complete details. Signed-off-by: Tim Chase <tim@chase2k.com> Signed-off-by: Chunwei Chen <david.chen@osnexus.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #563
This commit is contained in:
parent
d2f97b2a26
commit
b7c7008ba2
@ -40,6 +40,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [
|
|||||||
SPL_AC_SHRINK_CONTROL_STRUCT
|
SPL_AC_SHRINK_CONTROL_STRUCT
|
||||||
SPL_AC_RWSEM_SPINLOCK_IS_RAW
|
SPL_AC_RWSEM_SPINLOCK_IS_RAW
|
||||||
SPL_AC_RWSEM_ACTIVITY
|
SPL_AC_RWSEM_ACTIVITY
|
||||||
|
SPL_AC_RWSEM_ATOMIC_LONG_COUNT
|
||||||
SPL_AC_SCHED_RT_HEADER
|
SPL_AC_SCHED_RT_HEADER
|
||||||
SPL_AC_2ARGS_VFS_GETATTR
|
SPL_AC_2ARGS_VFS_GETATTR
|
||||||
SPL_AC_USLEEP_RANGE
|
SPL_AC_USLEEP_RANGE
|
||||||
@ -1341,6 +1342,31 @@ AC_DEFUN([SPL_AC_RWSEM_ACTIVITY], [
|
|||||||
EXTRA_KCFLAGS="$tmp_flags"
|
EXTRA_KCFLAGS="$tmp_flags"
|
||||||
])
|
])
|
||||||
|
|
||||||
|
dnl #
|
||||||
|
dnl # 4.8 API Change
|
||||||
|
dnl #
|
||||||
|
dnl # rwsem "->count" changed to atomic_long_t type
|
||||||
|
dnl #
|
||||||
|
AC_DEFUN([SPL_AC_RWSEM_ATOMIC_LONG_COUNT], [
|
||||||
|
AC_MSG_CHECKING(
|
||||||
|
[whether struct rw_semaphore has atomic_long_t member count])
|
||||||
|
tmp_flags="$EXTRA_KCFLAGS"
|
||||||
|
EXTRA_KCFLAGS="-Werror"
|
||||||
|
SPL_LINUX_TRY_COMPILE([
|
||||||
|
#include <linux/rwsem.h>
|
||||||
|
],[
|
||||||
|
DECLARE_RWSEM(dummy_semaphore);
|
||||||
|
(void) atomic_long_read(&dummy_semaphore.count);
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_RWSEM_ATOMIC_LONG_COUNT, 1,
|
||||||
|
[struct rw_semaphore has atomic_long_t member count])
|
||||||
|
],[
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
])
|
||||||
|
EXTRA_KCFLAGS="$tmp_flags"
|
||||||
|
])
|
||||||
|
|
||||||
dnl #
|
dnl #
|
||||||
dnl # 3.9 API change,
|
dnl # 3.9 API change,
|
||||||
dnl # Moved things from linux/sched.h to linux/sched/rt.h
|
dnl # Moved things from linux/sched.h to linux/sched/rt.h
|
||||||
|
@ -35,9 +35,12 @@
|
|||||||
#define SPL_RWSEM_SINGLE_WRITER_VALUE (RWSEM_ACTIVE_WRITE_BIAS)
|
#define SPL_RWSEM_SINGLE_WRITER_VALUE (RWSEM_ACTIVE_WRITE_BIAS)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Linux 3.16 change activity to count for rwsem-spinlock */
|
/* Linux 3.16 changed activity to count for rwsem-spinlock */
|
||||||
#ifdef HAVE_RWSEM_ACTIVITY
|
#if defined(HAVE_RWSEM_ACTIVITY)
|
||||||
#define RWSEM_COUNT(sem) sem->activity
|
#define RWSEM_COUNT(sem) sem->activity
|
||||||
|
/* Linux 4.8 changed count to an atomic_long_t for !rwsem-spinlock */
|
||||||
|
#elif defined(HAVE_RWSEM_ATOMIC_LONG_COUNT)
|
||||||
|
#define RWSEM_COUNT(sem) atomic_long_read(&(sem)->count)
|
||||||
#else
|
#else
|
||||||
#define RWSEM_COUNT(sem) sem->count
|
#define RWSEM_COUNT(sem) sem->count
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#define DEBUG_SUBSYSTEM S_RWLOCK
|
#define DEBUG_SUBSYSTEM S_RWLOCK
|
||||||
|
|
||||||
#ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
|
#if defined(CONFIG_RWSEM_GENERIC_SPINLOCK)
|
||||||
static int
|
static int
|
||||||
__rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
__rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
||||||
{
|
{
|
||||||
@ -47,6 +47,15 @@ __rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
|||||||
spl_rwsem_unlock_irqrestore(&rwsem->wait_lock, flags);
|
spl_rwsem_unlock_irqrestore(&rwsem->wait_lock, flags);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
#elif defined(HAVE_RWSEM_ATOMIC_LONG_COUNT)
|
||||||
|
static int
|
||||||
|
__rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
||||||
|
{
|
||||||
|
long val;
|
||||||
|
val = atomic_long_cmpxchg(&rwsem->count, SPL_RWSEM_SINGLE_READER_VALUE,
|
||||||
|
SPL_RWSEM_SINGLE_WRITER_VALUE);
|
||||||
|
return (val == SPL_RWSEM_SINGLE_READER_VALUE);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static int
|
static int
|
||||||
__rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
__rwsem_tryupgrade(struct rw_semaphore *rwsem)
|
||||||
|
Loading…
Reference in New Issue
Block a user