From 94232a4332de3bc210e7067fd43521b3eb12336a Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Mon, 22 Sep 2014 16:25:25 +0200 Subject: [PATCH] s390/rwlock: improve writer fairness Set the write-lock bit in the out-of-line rwlock code to indicate that a writer is waiting. Additional readers will no be able to get the lock until at least one writer got the lock. Additional writers have to wait for the first writer to release the lock again. Signed-off-by: Martin Schwidefsky --- arch/s390/lib/spinlock.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index c717f4a4c63e..01f29bb9c71b 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -149,9 +149,10 @@ EXPORT_SYMBOL(_raw_read_trylock_retry); void _raw_write_lock_wait(arch_rwlock_t *rw) { - unsigned int owner, old; + unsigned int owner, old, prev; int count = spin_retry; + prev = 0x80000000; owner = 0; while (1) { if (count-- <= 0) { @@ -161,10 +162,13 @@ void _raw_write_lock_wait(arch_rwlock_t *rw) } old = ACCESS_ONCE(rw->lock); owner = ACCESS_ONCE(rw->owner); - if (old) - continue; - if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000)) - return; + if ((int) old >= 0 && + _raw_compare_and_swap(&rw->lock, old, old | 0x80000000)) + prev = old; + else + smp_rmb(); + if ((old & 0x7fffffff) == 0 && (int) prev >= 0) + break; } } EXPORT_SYMBOL(_raw_write_lock_wait);