summarylogtreecommitdiffstats
path: root/linux-5.3-compat-rw_semaphore-owner.patch
blob: 3a46359ded3919e187b6f82e20222b9714ad3966 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
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);