summarylogtreecommitdiffstats
path: root/linux-5.3-compat-rw_semaphore-owner.patch
diff options
context:
space:
mode:
Diffstat (limited to 'linux-5.3-compat-rw_semaphore-owner.patch')
-rw-r--r--linux-5.3-compat-rw_semaphore-owner.patch155
1 files changed, 155 insertions, 0 deletions
diff --git a/linux-5.3-compat-rw_semaphore-owner.patch b/linux-5.3-compat-rw_semaphore-owner.patch
new file mode 100644
index 00000000000..3a46359ded3
--- /dev/null
+++ b/linux-5.3-compat-rw_semaphore-owner.patch
@@ -0,0 +1,155 @@
+From d4b15200e75a37da053589aa2ddff06872302ac2 Mon Sep 17 00:00:00 2001
+From: Brian Behlendorf <behlendorf1@llnl.gov>
+Date: Fri, 12 Jul 2019 13:27:24 -0700
+Subject: [PATCH] Linux 5.3 compat: rw_semaphore owner
+
+Commit https://github.com/torvalds/linux/commit/94a9717b updated the
+rwsem's owner field to contain additional flags describing the rwsem's
+state. Rather then update the wrappers to mask out these bits, the
+code no longer relies on the owner stored by the kernel. This does
+increase the size of a krwlock_t but it makes the implementation
+less sensitive to future kernel changes.
+
+Reviewed-by: Tony Hutter <hutter2@llnl.gov>
+Reviewed-by: Tomohiro Kusumi <kusumi.tomohiro@gmail.com>
+Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
+Closes #9029
+---
+ include/spl/sys/rwlock.h | 68 +++-------------------------------------
+ module/spl/spl-rwlock.c | 3 --
+ 2 files changed, 5 insertions(+), 66 deletions(-)
+
+diff --git a/include/spl/sys/rwlock.h b/include/spl/sys/rwlock.h
+index 408defac20d..5e052b532a4 100644
+--- a/include/spl/sys/rwlock.h
++++ b/include/spl/sys/rwlock.h
+@@ -78,15 +78,9 @@ typedef enum {
+ RW_READER = 2
+ } krw_t;
+
+-/*
+- * If CONFIG_RWSEM_SPIN_ON_OWNER is defined, rw_semaphore will have an owner
+- * field, so we don't need our own.
+- */
+ typedef struct {
+ struct rw_semaphore rw_rwlock;
+-#ifndef CONFIG_RWSEM_SPIN_ON_OWNER
+ kthread_t *rw_owner;
+-#endif
+ #ifdef CONFIG_LOCKDEP
+ krw_type_t rw_type;
+ #endif /* CONFIG_LOCKDEP */
+@@ -97,31 +91,19 @@ typedef struct {
+ static inline void
+ spl_rw_set_owner(krwlock_t *rwp)
+ {
+-/*
+- * If CONFIG_RWSEM_SPIN_ON_OWNER is defined, down_write, up_write,
+- * downgrade_write and __init_rwsem will set/clear owner for us.
+- */
+-#ifndef CONFIG_RWSEM_SPIN_ON_OWNER
+ rwp->rw_owner = current;
+-#endif
+ }
+
+ static inline void
+ spl_rw_clear_owner(krwlock_t *rwp)
+ {
+-#ifndef CONFIG_RWSEM_SPIN_ON_OWNER
+ rwp->rw_owner = NULL;
+-#endif
+ }
+
+ static inline kthread_t *
+ rw_owner(krwlock_t *rwp)
+ {
+-#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
+- return (SEM(rwp)->owner);
+-#else
+ return (rwp->rw_owner);
+-#endif
+ }
+
+ #ifdef CONFIG_LOCKDEP
+@@ -148,62 +130,22 @@ spl_rw_lockdep_on_maybe(krwlock_t *rwp) \
+ #define spl_rw_lockdep_on_maybe(rwp)
+ #endif /* CONFIG_LOCKDEP */
+
+-
+ static inline int
+-RW_WRITE_HELD(krwlock_t *rwp)
++RW_LOCK_HELD(krwlock_t *rwp)
+ {
+- return (rw_owner(rwp) == current);
++ return (spl_rwsem_is_locked(SEM(rwp)));
+ }
+
+ static inline int
+-RW_LOCK_HELD(krwlock_t *rwp)
++RW_WRITE_HELD(krwlock_t *rwp)
+ {
+- return (spl_rwsem_is_locked(SEM(rwp)));
++ return (rw_owner(rwp) == current);
+ }
+
+ static inline int
+ RW_READ_HELD(krwlock_t *rwp)
+ {
+- if (!RW_LOCK_HELD(rwp))
+- return (0);
+-
+- /*
+- * rw_semaphore cheat sheet:
+- *
+- * < 3.16:
+- * There's no rw_semaphore.owner, so use rwp.owner instead.
+- * If rwp.owner == NULL then it's a reader
+- *
+- * 3.16 - 4.7:
+- * rw_semaphore.owner added (https://lwn.net/Articles/596656/)
+- * and CONFIG_RWSEM_SPIN_ON_OWNER introduced.
+- * If rw_semaphore.owner == NULL then it's a reader
+- *
+- * 4.8 - 4.16.16:
+- * RWSEM_READER_OWNED added as an internal #define.
+- * (https://lore.kernel.org/patchwork/patch/678590/)
+- * If rw_semaphore.owner == 1 then it's a reader
+- *
+- * 4.16.17 - 4.19:
+- * RWSEM_OWNER_UNKNOWN introduced as ((struct task_struct *)-1L)
+- * (https://do-db2.lkml.org/lkml/2018/5/15/985)
+- * If rw_semaphore.owner == 1 then it's a reader.
+- *
+- * 4.20+:
+- * RWSEM_OWNER_UNKNOWN changed to ((struct task_struct *)-2L)
+- * (https://lkml.org/lkml/2018/9/6/986)
+- * If rw_semaphore.owner & 1 then it's a reader, and also the reader's
+- * task_struct may be embedded in rw_semaphore->owner.
+- */
+-#if defined(CONFIG_RWSEM_SPIN_ON_OWNER) && defined(RWSEM_OWNER_UNKNOWN)
+- if (RWSEM_OWNER_UNKNOWN == (struct task_struct *)-2L) {
+- /* 4.20+ kernels with CONFIG_RWSEM_SPIN_ON_OWNER */
+- return ((unsigned long) SEM(rwp)->owner & 1);
+- }
+-#endif
+-
+- /* < 4.20 kernel or !CONFIG_RWSEM_SPIN_ON_OWNER */
+- return (rw_owner(rwp) == NULL || (unsigned long) rw_owner(rwp) == 1);
++ return (RW_LOCK_HELD(rwp) && rw_owner(rwp) == NULL);
+ }
+
+ /*
+diff --git a/module/spl/spl-rwlock.c b/module/spl/spl-rwlock.c
+index 86727ed1957..886e16924e6 100644
+--- a/module/spl/spl-rwlock.c
++++ b/module/spl/spl-rwlock.c
+@@ -119,9 +119,6 @@ rwsem_tryupgrade(struct rw_semaphore *rwsem)
+ if (__rwsem_tryupgrade(rwsem)) {
+ rwsem_release(&rwsem->dep_map, 1, _RET_IP_);
+ rwsem_acquire(&rwsem->dep_map, 0, 1, _RET_IP_);
+-#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
+- rwsem->owner = current;
+-#endif
+ return (1);
+ }
+ return (0);