One copy of this logic is better than three.
Unified · Split
| @@ -285,6 +285,18 @@ static inline bool rwsem_read_trylock(struct rw_semaphore *sem) · 284 unmodified lines | ||
| 285 | 285 | return false; |
| 286 | 286 | } |
| 287 | 287 | |
| 288 | +static inline bool rwsem_write_trylock(struct rw_semaphore *sem) | |
| 289 | +{ | |
| 290 | + long tmp = RWSEM_UNLOCKED_VALUE; | |
| 291 | + | |
| 292 | + if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp, RWSEM_WRITER_LOCKED)) { | |
| 293 | + rwsem_set_owner(sem); | |
| 294 | + return true; | |
| 295 | + } | |
| 296 | + | |
| 297 | + return false; | |
| 298 | +} | |
| 299 | + | |
| 288 | 300 | /* |
| 289 | 301 | * Return just the real task structure pointer of the owner |
| 290 | 302 | */ |
| @@ -1395,42 +1407,24 @@ static inline int __down_read_trylock(struct rw_semaphore *sem) · 1104 unmodified lines | ||
| 1395 | 1407 | */ |
| 1396 | 1408 | static inline void __down_write(struct rw_semaphore *sem) |
| 1397 | 1409 | { |
| 1398 | − long tmp = RWSEM_UNLOCKED_VALUE; | |
| 1399 | − | |
| 1400 | − if (unlikely(!atomic_long_try_cmpxchg_acquire(&sem->count, &tmp, | |
| 1401 | − RWSEM_WRITER_LOCKED))) | |
| 1410 | + if (unlikely(!rwsem_write_trylock(sem))) | |
| 1402 | 1411 | rwsem_down_write_slowpath(sem, TASK_UNINTERRUPTIBLE); |
| 1403 | − else | |
| 1404 | − rwsem_set_owner(sem); | |
| 1405 | 1412 | } |
| 1406 | 1413 | |
| 1407 | 1414 | static inline int __down_write_killable(struct rw_semaphore *sem) |
| 1408 | 1415 | { |
| 1409 | − long tmp = RWSEM_UNLOCKED_VALUE; | |
| 1410 | − | |
| 1411 | − if (unlikely(!atomic_long_try_cmpxchg_acquire(&sem->count, &tmp, | |
| 1412 | − RWSEM_WRITER_LOCKED))) { | |
| 1416 | + if (unlikely(!rwsem_write_trylock(sem))) { | |
| 1413 | 1417 | if (IS_ERR(rwsem_down_write_slowpath(sem, TASK_KILLABLE))) |
| 1414 | 1418 | return -EINTR; |
| 1415 | − } else { | |
| 1416 | − rwsem_set_owner(sem); | |
| 1417 | 1419 | } |
| 1420 | + | |
| 1418 | 1421 | return 0; |
| 1419 | 1422 | } |
| 1420 | 1423 | |
| 1421 | 1424 | static inline int __down_write_trylock(struct rw_semaphore *sem) |
| 1422 | 1425 | { |
| 1423 | − long tmp; | |
| 1424 | − | |
| 1425 | 1426 | DEBUG_RWSEMS_WARN_ON(sem->magic != sem, sem); |
| 1426 | − | |
| 1427 | − tmp = RWSEM_UNLOCKED_VALUE; | |
| 1428 | − if (atomic_long_try_cmpxchg_acquire(&sem->count, &tmp, | |
| 1429 | − RWSEM_WRITER_LOCKED)) { | |
| 1430 | − rwsem_set_owner(sem); | |
| 1431 | − return true; | |
| 1432 | − } | |
| 1433 | − return false; | |
| 1427 | + return rwsem_write_trylock(sem); | |
| 1434 | 1428 | } |
| 1435 | 1429 | |
| 1436 | 1430 | /* |