mirror of https://github.com/archzfs/zfs-dkms
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.4 KiB
155 lines
4.4 KiB
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);
|
|
|