Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <schwidefsky@de.ibm.com>

+9 -5
+9 -5
arch/s390/lib/spinlock.c
··· 149 149 150 150 void _raw_write_lock_wait(arch_rwlock_t *rw) 151 151 { 152 - unsigned int owner, old; 152 + unsigned int owner, old, prev; 153 153 int count = spin_retry; 154 154 155 + prev = 0x80000000; 155 156 owner = 0; 156 157 while (1) { 157 158 if (count-- <= 0) { ··· 162 161 } 163 162 old = ACCESS_ONCE(rw->lock); 164 163 owner = ACCESS_ONCE(rw->owner); 165 - if (old) 166 - continue; 167 - if (_raw_compare_and_swap(&rw->lock, 0, 0x80000000)) 168 - return; 164 + if ((int) old >= 0 && 165 + _raw_compare_and_swap(&rw->lock, old, old | 0x80000000)) 166 + prev = old; 167 + else 168 + smp_rmb(); 169 + if ((old & 0x7fffffff) == 0 && (int) prev >= 0) 170 + break; 169 171 } 170 172 } 171 173 EXPORT_SYMBOL(_raw_write_lock_wait);