Skip to content

Commit

Permalink
locking/qrwlock: Reduce reader/writer to reader lock transfer latency
Browse files Browse the repository at this point in the history
Currently, a reader will check first to make sure that the writer mode
byte is cleared before incrementing the reader count. That waiting is
not really necessary. It increases the latency in the reader/writer
to reader transition and reduces readers performance.

This patch eliminates that waiting. It also has the side effect
of reducing the chance of writer lock stealing and improving the
fairness of the lock. Using a locking microbenchmark, a 10-threads 5M
locking loop of mostly readers (RW ratio = 10,000:1) has the following
performance numbers in a Haswell-EX box:

        Kernel          Locking Rate (Kops/s)
        ------          ---------------------
        4.1.1               15,063,081
        4.1.1+patch         17,241,552  (+14.4%)

Signed-off-by: Waiman Long <[email protected]>
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Cc: Andrew Morton <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Douglas Hatch <[email protected]>
Cc: Linus Torvalds <[email protected]>
Cc: Paul E. McKenney <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Scott J Norton <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Will Deacon <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Ingo Molnar <[email protected]>
  • Loading branch information
longman88 authored and Ingo Molnar committed Aug 3, 2015
1 parent 3b3fdf1 commit ffffeaf
Showing 1 changed file with 4 additions and 8 deletions.
12 changes: 4 additions & 8 deletions kernel/locking/qrwlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,11 @@ void queued_read_lock_slowpath(struct qrwlock *lock, u32 cnts)
arch_spin_lock(&lock->lock);

/*
* At the head of the wait queue now, wait until the writer state
* goes to 0 and then try to increment the reader count and get
* the lock. It is possible that an incoming writer may steal the
* lock in the interim, so it is necessary to check the writer byte
* to make sure that the write lock isn't taken.
* At the head of the wait queue now, increment the reader count
* and wait until the writer, if it has the lock, has gone away.
* At ths stage, it is not possible for a writer to remain in the
* waiting state (_QW_WAITING). So there won't be any deadlock.
*/
while (atomic_read(&lock->cnts) & _QW_WMASK)
cpu_relax_lowlatency();

cnts = atomic_add_return(_QR_BIAS, &lock->cnts) - _QR_BIAS;
rspin_until_writer_unlock(lock, cnts);

Expand Down

0 comments on commit ffffeaf

Please sign in to comment.