diff options
Diffstat (limited to 'linux-5.3-compat-rw_semaphore-owner.patch')
-rw-r--r-- | linux-5.3-compat-rw_semaphore-owner.patch | 155 |
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 000000000000..3a46359ded39 --- /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); |