Skip to content

Commit 9b0fc9c

Browse files
walken-googletorvalds
authored andcommitted
rwsem: skip initial trylock in rwsem_down_write_failed
We can skip the initial trylock in rwsem_down_write_failed() if there are known active lockers already, thus saving one likely-to-fail cmpxchg. Signed-off-by: Michel Lespinasse <walken@google.com> Reviewed-by: Peter Hurley <peter@hurleysoftware.com> Acked-by: Davidlohr Bueso <davidlohr.bueso@hp.com> Acked-by: Rik van Riel <riel@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent a7d2c57 commit 9b0fc9c

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

lib/rwsem.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -216,22 +216,23 @@ struct rw_semaphore __sched *rwsem_down_write_failed(struct rw_semaphore *sem)
216216
/* wait until we successfully acquire the lock */
217217
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
218218
while (true) {
219-
220-
/* Try acquiring the write lock. */
221-
count = RWSEM_ACTIVE_WRITE_BIAS;
222-
if (!list_is_singular(&sem->wait_list))
223-
count += RWSEM_WAITING_BIAS;
224-
if (cmpxchg(&sem->count, RWSEM_WAITING_BIAS, count) ==
219+
if (!(count & RWSEM_ACTIVE_MASK)) {
220+
/* Try acquiring the write lock. */
221+
count = RWSEM_ACTIVE_WRITE_BIAS;
222+
if (!list_is_singular(&sem->wait_list))
223+
count += RWSEM_WAITING_BIAS;
224+
if (cmpxchg(&sem->count, RWSEM_WAITING_BIAS, count) ==
225225
RWSEM_WAITING_BIAS)
226-
break;
226+
break;
227+
}
227228

228229
raw_spin_unlock_irq(&sem->wait_lock);
229230

230231
/* Block until there are no active lockers. */
231232
do {
232233
schedule();
233234
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
234-
} while (sem->count & RWSEM_ACTIVE_MASK);
235+
} while ((count = sem->count) & RWSEM_ACTIVE_MASK);
235236

236237
raw_spin_lock_irq(&sem->wait_lock);
237238
}

0 commit comments

Comments
 (0)