|
133 | 133 | * the owner value concurrently without lock. Read from owner, however,
|
134 | 134 | * may not need READ_ONCE() as long as the pointer value is only used
|
135 | 135 | * for comparison and isn't being dereferenced.
|
| 136 | + * |
| 137 | + * Both rwsem_{set,clear}_owner() functions should be in the same |
| 138 | + * preempt disable section as the atomic op that changes sem->count. |
136 | 139 | */
|
137 | 140 | static inline void rwsem_set_owner(struct rw_semaphore *sem)
|
138 | 141 | {
|
| 142 | + lockdep_assert_preemption_disabled(); |
139 | 143 | atomic_long_set(&sem->owner, (long)current);
|
140 | 144 | }
|
141 | 145 |
|
142 | 146 | static inline void rwsem_clear_owner(struct rw_semaphore *sem)
|
143 | 147 | {
|
| 148 | + lockdep_assert_preemption_disabled(); |
144 | 149 | atomic_long_set(&sem->owner, 0);
|
145 | 150 | }
|
146 | 151 |
|
@@ -251,13 +256,16 @@ static inline bool rwsem_read_trylock(struct rw_semaphore *sem, long *cntp)
|
251 | 256 | static inline bool rwsem_write_trylock(struct rw_semaphore *sem)
|
252 | 257 | {
|
253 | 258 | long tmp = RWSEM_UNLOCKED_VALUE;
|
| 259 | + bool ret = false; |
254 | 260 |
|
| 261 | + preempt_disable(); |
255 | 262 | if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp, RWSEM_WRITER_LOCKED)) {
|
256 | 263 | rwsem_set_owner(sem);
|
257 |
| - return true; |
| 264 | + ret = true; |
258 | 265 | }
|
259 | 266 |
|
260 |
| - return false; |
| 267 | + preempt_enable(); |
| 268 | + return ret; |
261 | 269 | }
|
262 | 270 |
|
263 | 271 | /*
|
@@ -1352,8 +1360,10 @@ static inline void __up_write(struct rw_semaphore *sem)
|
1352 | 1360 | DEBUG_RWSEMS_WARN_ON((rwsem_owner(sem) != current) &&
|
1353 | 1361 | !rwsem_test_oflags(sem, RWSEM_NONSPINNABLE), sem);
|
1354 | 1362 |
|
| 1363 | + preempt_disable(); |
1355 | 1364 | rwsem_clear_owner(sem);
|
1356 | 1365 | tmp = atomic_long_fetch_add_release(-RWSEM_WRITER_LOCKED, &sem->count);
|
| 1366 | + preempt_enable(); |
1357 | 1367 | if (unlikely(tmp & RWSEM_FLAG_WAITERS))
|
1358 | 1368 | rwsem_wake(sem);
|
1359 | 1369 | }
|
|
0 commit comments