]> git.proxmox.com Git - mirror_spl.git/blobdiff - include/linux/rwsem_compat.h
Make include/linux/ conform to ZFS style standard
[mirror_spl.git] / include / linux / rwsem_compat.h
index 80f348e4c25abbe6556970090fc38975376275b8..7a0dcf8dc3fe611178356ed5bd29ef2fd658f64e 100644 (file)
@@ -1,4 +1,4 @@
-/*****************************************************************************\
+/*
  *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
  *  Copyright (C) 2007 The Regents of the University of California.
  *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
  *
  *  You should have received a copy of the GNU General Public License along
  *  with the SPL.  If not, see <http://www.gnu.org/licenses/>.
-\*****************************************************************************/
+ */
 
 #ifndef _SPL_RWSEM_COMPAT_H
-#define _SPL_RWSEM_COMPAT_H
+#define        _SPL_RWSEM_COMPAT_H
 
 #include <linux/rwsem.h>
 
-#if defined(RWSEM_SPINLOCK_IS_RAW)
-#define spl_rwsem_lock_irqsave(lk, fl)       raw_spin_lock_irqsave(lk, fl)
-#define spl_rwsem_unlock_irqrestore(lk, fl)  raw_spin_unlock_irqrestore(lk, fl)
-#define spl_rwsem_trylock_irqsave(lk, fl)    raw_spin_trylock_irqsave(lk, fl)
+#if defined(CONFIG_PREEMPT_RT_FULL)
+#define        SPL_RWSEM_SINGLE_READER_VALUE   (1)
+#define        SPL_RWSEM_SINGLE_WRITER_VALUE   (0)
+#elif defined(CONFIG_RWSEM_GENERIC_SPINLOCK)
+#define        SPL_RWSEM_SINGLE_READER_VALUE   (1)
+#define        SPL_RWSEM_SINGLE_WRITER_VALUE   (-1)
 #else
-#define spl_rwsem_lock_irqsave(lk, fl)       spin_lock_irqsave(lk, fl)
-#define spl_rwsem_unlock_irqrestore(lk, fl)  spin_unlock_irqrestore(lk, fl)
-#define spl_rwsem_trylock_irqsave(lk, fl)    spin_trylock_irqsave(lk, fl)
-#endif /* RWSEM_SPINLOCK_IS_RAW */
+#define        SPL_RWSEM_SINGLE_READER_VALUE   (RWSEM_ACTIVE_READ_BIAS)
+#define        SPL_RWSEM_SINGLE_WRITER_VALUE   (RWSEM_ACTIVE_WRITE_BIAS)
+#endif
 
-/*
- * Prior to Linux 2.6.33 there existed a race condition in rwsem_is_locked().
- * The semaphore's activity was checked outside of the wait_lock which
- * could result in some readers getting the incorrect activity value.
- *
- * When a kernel without this fix is detected the SPL takes responsibility
- * for acquiring the wait_lock to avoid this race.
- */
-#if defined(RWSEM_IS_LOCKED_TAKES_WAIT_LOCK)
-#define spl_rwsem_is_locked(rwsem)           rwsem_is_locked(rwsem)
+/* Linux 3.16 changed activity to count for rwsem-spinlock */
+#if defined(CONFIG_PREEMPT_RT_FULL)
+#define        RWSEM_COUNT(sem)        sem->read_depth
+#elif defined(HAVE_RWSEM_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
-static inline int
-spl_rwsem_is_locked(struct rw_semaphore *rwsem)
-{
-       unsigned long flags;
-       int rc = 1;
+#define        RWSEM_COUNT(sem)        sem->count
+#endif
+
+int rwsem_tryupgrade(struct rw_semaphore *rwsem);
 
-       if (spl_rwsem_trylock_irqsave(&rwsem->wait_lock, flags)) {
-               rc = rwsem_is_locked(rwsem);
-               spl_rwsem_unlock_irqrestore(&rwsem->wait_lock, flags);
-       }
+#if defined(RWSEM_SPINLOCK_IS_RAW)
+#define        spl_rwsem_lock_irqsave(lk, fl)          raw_spin_lock_irqsave(lk, fl)
+#define        spl_rwsem_unlock_irqrestore(lk, fl)     \
+    raw_spin_unlock_irqrestore(lk, fl)
+#define        spl_rwsem_trylock_irqsave(lk, fl)       raw_spin_trylock_irqsave(lk, fl)
+#else
+#define        spl_rwsem_lock_irqsave(lk, fl)          spin_lock_irqsave(lk, fl)
+#define        spl_rwsem_unlock_irqrestore(lk, fl)     spin_unlock_irqrestore(lk, fl)
+#define        spl_rwsem_trylock_irqsave(lk, fl)       spin_trylock_irqsave(lk, fl)
+#endif /* RWSEM_SPINLOCK_IS_RAW */
 
-       return (rc);
-}
-#endif /* RWSEM_IS_LOCKED_TAKES_WAIT_LOCK */
+#define        spl_rwsem_is_locked(rwsem)              rwsem_is_locked(rwsem)
 
 #endif /* _SPL_RWSEM_COMPAT_H */