]> granicus.if.org Git - zfs/commitdiff
Linux 3.2 compat: rw_semaphore.wait_lock is raw
authorDarik Horn <dajhorn@vanadac.com>
Wed, 11 Jan 2012 17:44:34 +0000 (11:44 -0600)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 12 Jan 2012 00:28:05 +0000 (16:28 -0800)
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 <behlendorf1@llnl.gov>
Closes: #76
Closes: zfsonlinux/zfs#463
config/spl-build.m4
configure
include/linux/rwsem_compat.h
include/sys/rwlock.h
spl_config.h.in

index 90ff680840fb6b248b13335f5b30d25424083984..27b2c429815043494f1c56e25b95dcf9f65fdaf5 100644 (file)
@@ -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"
+])
index 9d95d7654f69ae23d340aa24942051c4d203e401..621773d9d5ed96d832693d6f55695648fffed22f 100755 (executable)
--- a/configure
+++ b/configure
 
 
 
+
+       { $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)
 
 
 
+       { $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)                        ;;
                 *)
index 67a82bb444bcf0fa8b2c7643753ef4e5304d855d..fe69f01548df42e97e0c0a7d8344fb8e4c885ee9 100644 (file)
 
 #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
 
 #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 */
index 3d9808599c6d3cd7ad28c81ce079edec78cbe013..9d29ad679fa89522df794b6d1b0f763de4e84bf0 100644 (file)
@@ -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
index 94e28e70d30dc2ac5fda759f82563b817b990833..847da2137a797b3c84b0fe571b3d44ebb8da3967 100644 (file)
 /* 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