diff options
author | Darik Horn <[email protected]> | 2012-01-11 11:44:34 -0600 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2012-01-11 16:28:05 -0800 |
commit | 588d900433b03e33e4bbbfee7309bd15f71148fb (patch) | |
tree | f5176c56eb87832d869e9092a710e7d74980d6f7 | |
parent | 5f6c14b1eda9c7b47d11a3b90e78dea6a7f429e0 (diff) |
Linux 3.2 compat: rw_semaphore.wait_lock is raw
The wait_lock member of the rw_semaphore struct became a raw_spinlock_t
in Linux 3.2 at torvalds/linux@ddb6c9b58a19edcfac93ac670b066c836ff729f1.
Wrap spin_lock_* function calls in a new spl_rwsem_* interface to
ensure type safety if raw_spinlock_t becomes architecture specific,
and to satisfy these compiler warnings:
warning: passing argument 1 of ‘spinlock_check’
from incompatible pointer type [enabled by default]
note: expected ‘struct spinlock_t *’
but argument is of type ‘struct raw_spinlock_t *’
Signed-off-by: Brian Behlendorf <[email protected]>
Closes: #76
Closes: zfsonlinux/zfs#463
-rw-r--r-- | config/spl-build.m4 | 27 | ||||
-rwxr-xr-x | configure | 140 | ||||
-rw-r--r-- | include/linux/rwsem_compat.h | 36 | ||||
-rw-r--r-- | include/sys/rwlock.h | 16 | ||||
-rw-r--r-- | spl_config.h.in | 3 |
5 files changed, 206 insertions, 16 deletions
diff --git a/config/spl-build.m4 b/config/spl-build.m4 index 90ff68084..27b2c4298 100644 --- a/config/spl-build.m4 +++ b/config/spl-build.m4 @@ -85,6 +85,7 @@ AC_DEFUN([SPL_AC_CONFIG_KERNEL], [ SPL_AC_KERN_PATH_PARENT_SYMBOL SPL_AC_2ARGS_ZLIB_DEFLATE_WORKSPACESIZE SPL_AC_SHRINK_CONTROL_STRUCT + SPL_AC_RWSEM_SPINLOCK_IS_RAW ]) AC_DEFUN([SPL_AC_MODULE_SYMVERS], [ @@ -1973,3 +1974,29 @@ AC_DEFUN([SPL_AC_SHRINK_CONTROL_STRUCT], [ AC_MSG_RESULT(no) ]) ]) + +dnl # +dnl # 3.1 API Change +dnl # +dnl # The rw_semaphore.wait_lock member was changed from spinlock_t to +dnl # raw_spinlock_t at commit ddb6c9b58a19edcfac93ac670b066c836ff729f1. +dnl # +AC_DEFUN([SPL_AC_RWSEM_SPINLOCK_IS_RAW], [ + AC_MSG_CHECKING([whether struct rw_semaphore member wait_lock is raw]) + tmp_flags="$EXTRA_KCFLAGS" + EXTRA_KCFLAGS="-Werror" + SPL_LINUX_TRY_COMPILE([ + #include <linux/rwsem.h> + ],[ + struct rw_semaphore dummy_semaphore __attribute__ ((unused)); + raw_spinlock_t dummy_lock __attribute__ ((unused)); + dummy_semaphore.wait_lock = dummy_lock; + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(RWSEM_SPINLOCK_IS_RAW, 1, + [struct rw_semaphore member wait_lock is raw_spinlock_t]) + ],[ + AC_MSG_RESULT(no) + ]) + EXTRA_KCFLAGS="$tmp_flags" +]) @@ -16025,6 +16025,76 @@ fi + + { $as_echo "$as_me:$LINENO: checking whether struct rw_semaphore member wait_lock is raw" >&5 +$as_echo_n "checking whether struct rw_semaphore member wait_lock is raw... " >&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/rwsem.h> + +int +main (void) +{ + + struct rw_semaphore dummy_semaphore __attribute__ ((unused)); + raw_spinlock_t dummy_lock __attribute__ ((unused)); + dummy_semaphore.wait_lock = dummy_lock; + + ; + 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 RWSEM_SPINLOCK_IS_RAW 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" + ;; user) ;; all) @@ -20335,6 +20405,76 @@ fi + { $as_echo "$as_me:$LINENO: checking whether struct rw_semaphore member wait_lock is raw" >&5 +$as_echo_n "checking whether struct rw_semaphore member wait_lock is raw... " >&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/rwsem.h> + +int +main (void) +{ + + struct rw_semaphore dummy_semaphore __attribute__ ((unused)); + raw_spinlock_t dummy_lock __attribute__ ((unused)); + dummy_semaphore.wait_lock = dummy_lock; + + ; + 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 RWSEM_SPINLOCK_IS_RAW 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" + + ;; srpm) ;; *) diff --git a/include/linux/rwsem_compat.h b/include/linux/rwsem_compat.h index 67a82bb44..fe69f0154 100644 --- a/include/linux/rwsem_compat.h +++ b/include/linux/rwsem_compat.h @@ -27,6 +27,26 @@ #include <linux/rwsem.h> +#ifdef RWSEM_SPINLOCK_IS_RAW +#define spl_rwsem_lock_irqsave(lock, flags) \ +({ \ + raw_spin_lock_irqsave(lock, flags); \ +}) +#define spl_rwsem_unlock_irqrestore(lock, flags) \ +({ \ + raw_spin_unlock_irqrestore(lock, flags); \ +}) +#else +#define spl_rwsem_lock_irqsave(lock, flags) \ +({ \ + spin_lock_irqsave(lock, flags); \ +}) +#define spl_rwsem_unlock_irqrestore(lock, flags) \ +({ \ + spin_unlock_irqrestore(lock, flags); \ +}) +#endif /* RWSEM_SPINLOCK_IS_RAW */ + #ifdef RWSEM_IS_LOCKED_TAKES_WAIT_LOCK /* * A race condition in rwsem_is_locked() was fixed in Linux 2.6.33 and the fix @@ -48,14 +68,14 @@ #else -#define spl_rwsem_is_locked(rwsem) \ -({ \ - unsigned long _flags_; \ - int _rc_; \ - spin_lock_irqsave(&rwsem->wait_lock, _flags_); \ - _rc_ = rwsem_is_locked(rwsem); \ - spin_unlock_irqrestore(&rwsem->wait_lock, _flags_); \ - _rc_; \ +#define spl_rwsem_is_locked(rwsem) \ +({ \ + unsigned long _flags_; \ + int _rc_; \ + spl_rwsem_lock_irqsave(&rwsem->wait_lock, _flags_); \ + _rc_ = rwsem_is_locked(rwsem); \ + spl_rwsem_unlock_irqrestore(&rwsem->wait_lock, _flags_); \ + _rc_; \ }) #endif /* RWSEM_IS_LOCKED_TAKES_WAIT_LOCK */ diff --git a/include/sys/rwlock.h b/include/sys/rwlock.h index 3d9808599..9d29ad679 100644 --- a/include/sys/rwlock.h +++ b/include/sys/rwlock.h @@ -52,9 +52,9 @@ spl_rw_set_owner(krwlock_t *rwp) { unsigned long flags; - spin_lock_irqsave(&SEM(rwp)->wait_lock, flags); + spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, flags); rwp->rw_owner = current; - spin_unlock_irqrestore(&SEM(rwp)->wait_lock, flags); + spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, flags); } static inline void @@ -62,9 +62,9 @@ spl_rw_clear_owner(krwlock_t *rwp) { unsigned long flags; - spin_lock_irqsave(&SEM(rwp)->wait_lock, flags); + spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, flags); rwp->rw_owner = NULL; - spin_unlock_irqrestore(&SEM(rwp)->wait_lock, flags); + spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, flags); } static inline kthread_t * @@ -73,9 +73,9 @@ rw_owner(krwlock_t *rwp) unsigned long flags; kthread_t *owner; - spin_lock_irqsave(&SEM(rwp)->wait_lock, flags); + spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, flags); owner = rwp->rw_owner; - spin_unlock_irqrestore(&SEM(rwp)->wait_lock, flags); + spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, flags); return owner; } @@ -187,14 +187,14 @@ extern int __down_write_trylock_locked(struct rw_semaphore *); unsigned long _flags_; \ int _rc_ = 0; \ \ - spin_lock_irqsave(&SEM(rwp)->wait_lock, _flags_); \ + spl_rwsem_lock_irqsave(&SEM(rwp)->wait_lock, _flags_); \ if ((list_empty(&SEM(rwp)->wait_list)) && \ (SEM(rwp)->activity == 1)) { \ __up_read_locked(SEM(rwp)); \ VERIFY(_rc_ = __down_write_trylock_locked(SEM(rwp))); \ (rwp)->rw_owner = current; \ } \ - spin_unlock_irqrestore(&SEM(rwp)->wait_lock, _flags_); \ + spl_rwsem_unlock_irqrestore(&SEM(rwp)->wait_lock, _flags_); \ _rc_; \ }) #else diff --git a/spl_config.h.in b/spl_config.h.in index 94e28e70d..847da2137 100644 --- a/spl_config.h.in +++ b/spl_config.h.in @@ -271,6 +271,9 @@ /* rwsem_is_locked() acquires sem->wait_lock */ #undef RWSEM_IS_LOCKED_TAKES_WAIT_LOCK +/* struct rw_semaphore member wait_lock is raw_spinlock_t */ +#undef RWSEM_SPINLOCK_IS_RAW + /* Define the project alias string. */ #undef SPL_META_ALIAS |