s390/rwlock: improve writer fairness
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 22 Sep 2014 14:25:25 +0000 (16:25 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 25 Sep 2014 08:52:12 +0000 (10:52 +0200)
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 <schwidefsky@de.ibm.com>
arch/s390/lib/spinlock.c

index c717f4a4c63e696a46e109fc2fb2cd3112d46d63..01f29bb9c71b929edb2e74a771291026f8007d7a 100644 (file)
@@ -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);