|
@@ -80,7 +80,7 @@ void __init_rwsem(struct rw_semaphore *sem, const char *name,
|
|
|
debug_check_no_locks_freed((void *)sem, sizeof(*sem));
|
|
|
lockdep_init_map(&sem->dep_map, name, key, 0);
|
|
|
#endif
|
|
|
- sem->count = RWSEM_UNLOCKED_VALUE;
|
|
|
+ atomic_long_set(&sem->count, RWSEM_UNLOCKED_VALUE);
|
|
|
raw_spin_lock_init(&sem->wait_lock);
|
|
|
INIT_LIST_HEAD(&sem->wait_list);
|
|
|
#ifdef CONFIG_RWSEM_SPIN_ON_OWNER
|
|
@@ -153,10 +153,11 @@ __rwsem_mark_wake(struct rw_semaphore *sem,
|
|
|
if (wake_type != RWSEM_WAKE_READ_OWNED) {
|
|
|
adjustment = RWSEM_ACTIVE_READ_BIAS;
|
|
|
try_reader_grant:
|
|
|
- oldcount = rwsem_atomic_update(adjustment, sem) - adjustment;
|
|
|
+ oldcount = atomic_long_add_return(adjustment, &sem->count) - adjustment;
|
|
|
+
|
|
|
if (unlikely(oldcount < RWSEM_WAITING_BIAS)) {
|
|
|
/* A writer stole the lock. Undo our reader grant. */
|
|
|
- if (rwsem_atomic_update(-adjustment, sem) &
|
|
|
+ if (atomic_long_sub_return(adjustment, &sem->count) &
|
|
|
RWSEM_ACTIVE_MASK)
|
|
|
goto out;
|
|
|
/* Last active locker left. Retry waking readers. */
|
|
@@ -186,7 +187,7 @@ __rwsem_mark_wake(struct rw_semaphore *sem,
|
|
|
adjustment -= RWSEM_WAITING_BIAS;
|
|
|
|
|
|
if (adjustment)
|
|
|
- rwsem_atomic_add(adjustment, sem);
|
|
|
+ atomic_long_add(adjustment, &sem->count);
|
|
|
|
|
|
next = sem->wait_list.next;
|
|
|
loop = woken;
|
|
@@ -233,7 +234,7 @@ struct rw_semaphore __sched *rwsem_down_read_failed(struct rw_semaphore *sem)
|
|
|
list_add_tail(&waiter.list, &sem->wait_list);
|
|
|
|
|
|
/* we're now waiting on the lock, but no longer actively locking */
|
|
|
- count = rwsem_atomic_update(adjustment, sem);
|
|
|
+ count = atomic_long_add_return(adjustment, &sem->count);
|
|
|
|
|
|
/* If there are no active locks, wake the front queued process(es).
|
|
|
*
|
|
@@ -282,7 +283,8 @@ static inline bool rwsem_try_write_lock(long count, struct rw_semaphore *sem)
|
|
|
RWSEM_ACTIVE_WRITE_BIAS :
|
|
|
RWSEM_ACTIVE_WRITE_BIAS + RWSEM_WAITING_BIAS;
|
|
|
|
|
|
- if (cmpxchg_acquire(&sem->count, RWSEM_WAITING_BIAS, count) == RWSEM_WAITING_BIAS) {
|
|
|
+ if (atomic_long_cmpxchg_acquire(&sem->count, RWSEM_WAITING_BIAS, count)
|
|
|
+ == RWSEM_WAITING_BIAS) {
|
|
|
rwsem_set_owner(sem);
|
|
|
return true;
|
|
|
}
|
|
@@ -296,13 +298,13 @@ static inline bool rwsem_try_write_lock(long count, struct rw_semaphore *sem)
|
|
|
*/
|
|
|
static inline bool rwsem_try_write_lock_unqueued(struct rw_semaphore *sem)
|
|
|
{
|
|
|
- long old, count = READ_ONCE(sem->count);
|
|
|
+ long old, count = atomic_long_read(&sem->count);
|
|
|
|
|
|
while (true) {
|
|
|
if (!(count == 0 || count == RWSEM_WAITING_BIAS))
|
|
|
return false;
|
|
|
|
|
|
- old = cmpxchg_acquire(&sem->count, count,
|
|
|
+ old = atomic_long_cmpxchg_acquire(&sem->count, count,
|
|
|
count + RWSEM_ACTIVE_WRITE_BIAS);
|
|
|
if (old == count) {
|
|
|
rwsem_set_owner(sem);
|
|
@@ -324,7 +326,7 @@ static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem)
|
|
|
rcu_read_lock();
|
|
|
owner = READ_ONCE(sem->owner);
|
|
|
if (!owner) {
|
|
|
- long count = READ_ONCE(sem->count);
|
|
|
+ long count = atomic_long_read(&sem->count);
|
|
|
/*
|
|
|
* If sem->owner is not set, yet we have just recently entered the
|
|
|
* slowpath with the lock being active, then there is a possibility
|
|
@@ -375,7 +377,7 @@ bool rwsem_spin_on_owner(struct rw_semaphore *sem, struct task_struct *owner)
|
|
|
* held by readers. Check the counter to verify the
|
|
|
* state.
|
|
|
*/
|
|
|
- count = READ_ONCE(sem->count);
|
|
|
+ count = atomic_long_read(&sem->count);
|
|
|
return (count == 0 || count == RWSEM_WAITING_BIAS);
|
|
|
}
|
|
|
|
|
@@ -460,7 +462,7 @@ __rwsem_down_write_failed_common(struct rw_semaphore *sem, int state)
|
|
|
WAKE_Q(wake_q);
|
|
|
|
|
|
/* undo write bias from down_write operation, stop active locking */
|
|
|
- count = rwsem_atomic_update(-RWSEM_ACTIVE_WRITE_BIAS, sem);
|
|
|
+ count = atomic_long_sub_return(RWSEM_ACTIVE_WRITE_BIAS, &sem->count);
|
|
|
|
|
|
/* do optimistic spinning and steal lock if possible */
|
|
|
if (rwsem_optimistic_spin(sem))
|
|
@@ -483,7 +485,7 @@ __rwsem_down_write_failed_common(struct rw_semaphore *sem, int state)
|
|
|
|
|
|
/* we're now waiting on the lock, but no longer actively locking */
|
|
|
if (waiting) {
|
|
|
- count = READ_ONCE(sem->count);
|
|
|
+ count = atomic_long_read(&sem->count);
|
|
|
|
|
|
/*
|
|
|
* If there were already threads queued before us and there are
|
|
@@ -505,7 +507,7 @@ __rwsem_down_write_failed_common(struct rw_semaphore *sem, int state)
|
|
|
}
|
|
|
|
|
|
} else
|
|
|
- count = rwsem_atomic_update(RWSEM_WAITING_BIAS, sem);
|
|
|
+ count = atomic_long_add_return(RWSEM_WAITING_BIAS, &sem->count);
|
|
|
|
|
|
/* wait until we successfully acquire the lock */
|
|
|
set_current_state(state);
|
|
@@ -521,7 +523,7 @@ __rwsem_down_write_failed_common(struct rw_semaphore *sem, int state)
|
|
|
|
|
|
schedule();
|
|
|
set_current_state(state);
|
|
|
- } while ((count = sem->count) & RWSEM_ACTIVE_MASK);
|
|
|
+ } while ((count = atomic_long_read(&sem->count)) & RWSEM_ACTIVE_MASK);
|
|
|
|
|
|
raw_spin_lock_irq(&sem->wait_lock);
|
|
|
}
|
|
@@ -536,7 +538,7 @@ out_nolock:
|
|
|
raw_spin_lock_irq(&sem->wait_lock);
|
|
|
list_del(&waiter.list);
|
|
|
if (list_empty(&sem->wait_list))
|
|
|
- rwsem_atomic_update(-RWSEM_WAITING_BIAS, sem);
|
|
|
+ atomic_long_add(-RWSEM_WAITING_BIAS, &sem->count);
|
|
|
else
|
|
|
__rwsem_mark_wake(sem, RWSEM_WAKE_ANY, &wake_q);
|
|
|
raw_spin_unlock_irq(&sem->wait_lock);
|