[SRU][Artful][PATCH 1/1] UBUNTU: SAUCE: (no-up) s390: fix rwlock implementation
Kleber Souza
kleber.souza at canonical.com
Fri May 11 13:26:06 UTC 2018
On 05/11/18 14:04, Joseph Salisbury wrote:
> On 05/11/2018 06:54 AM, Kleber Souza wrote:
>> On 05/07/18 23:59, Joseph Salisbury wrote:
>>> From: Heiko Carstens <heiko.carstens at de.ibm.com>
>>>
>>> BugLink: http://bugs.launchpad.net/bugs/1761674
>>>
>>> Description: kernel: fix rwlock implementation
>>> Symptom: Kernel hangs, due to deadlock on an rwlock.
>>> Problem: With upstream commit 94232a4332de ("s390/rwlock: improve writer
>>> fairness") rwlock writer fairness was supposed to be
>>> implemented. If a writer tries to take an rwlock it sets
>>> unconditionally the writer bit within the lock word and waits
>>> until all readers have released the lock. This however can lead
>>> to a deadlock since rwlocks can be taken recursively by readers.
>>> If e.g. CPU 0 holds the lock as a reader, and CPU 1 wants to
>>> write-lock the lock, then CPU 1 sets the writer bit and
>>> afterwards busy waits for CPU 0 to release the lock. If now CPU 0
>>> tries to read-lock the lock again (recursively) it will also busy
>>> wait until CPU 1 removes the writer bit, which will never happen,
>>> since it waits for the first reader on CPU 0 to release the lock.
>>> Solution: Revert the rwlock writer fairness semantics again.
>>>
>>> Signed-off-by: Joseph Salisbury <joseph.salisbury at canonical.com>
>> Shouldn't the patch have a sign-off from the original author as well?th
> Whoops, yes it should. Want me to NAK this one and send a v2 with the SOB?
Hi Joe,
Could you please send a v2?
Thanks,
Kleber
>>
>>
>> Thanks,
>> Kleber
>>
>>> ---
>>> arch/s390/lib/spinlock.c | 46 +++++++++-------------------------------------
>>> 1 file changed, 9 insertions(+), 37 deletions(-)
>>>
>>> diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c
>>> index ffb15bd..b3d5e7a 100644
>>> --- a/arch/s390/lib/spinlock.c
>>> +++ b/arch/s390/lib/spinlock.c
>>> @@ -174,40 +174,18 @@ int _raw_read_trylock_retry(arch_rwlock_t *rw)
>>> EXPORT_SYMBOL(_raw_read_trylock_retry);
>>>
>>> #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
>>> -
>>> void _raw_write_lock_wait(arch_rwlock_t *rw, int prev)
>>> -{
>>> - int count = spin_retry;
>>> - int owner, old;
>>> -
>>> - owner = 0;
>>> - while (1) {
>>> - if (count-- <= 0) {
>>> - if (owner && arch_vcpu_is_preempted(~owner))
>>> - smp_yield_cpu(~owner);
>>> - count = spin_retry;
>>> - }
>>> - old = ACCESS_ONCE(rw->lock);
>>> - owner = ACCESS_ONCE(rw->owner);
>>> - smp_mb();
>>> - if (old >= 0) {
>>> - prev = __RAW_LOCK(&rw->lock, 0x80000000, __RAW_OP_OR);
>>> - old = prev;
>>> - }
>>> - if ((old & 0x7fffffff) == 0 && prev >= 0)
>>> - break;
>>> - }
>>> -}
>>> -EXPORT_SYMBOL(_raw_write_lock_wait);
>>> -
>>> -#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */
>>> -
>>> +#else
>>> void _raw_write_lock_wait(arch_rwlock_t *rw)
>>> +#endif
>>> {
>>> int count = spin_retry;
>>> - int owner, old, prev;
>>> + int owner, old;
>>>
>>> - prev = 0x80000000;
>>> +#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
>>> + if ((int) prev > 0)
>>> + __RAW_UNLOCK(&rw->lock, 0x7fffffff, __RAW_OP_AND);
>>> +#endif
>>> owner = 0;
>>> while (1) {
>>> if (count-- <= 0) {
>>> @@ -217,19 +195,13 @@ void _raw_write_lock_wait(arch_rwlock_t *rw)
>>> }
>>> old = ACCESS_ONCE(rw->lock);
>>> owner = ACCESS_ONCE(rw->owner);
>>> - if (old >= 0 &&
>>> - __atomic_cmpxchg_bool(&rw->lock, old, old | 0x80000000))
>>> - prev = old;
>>> - else
>>> - smp_mb();
>>> - if ((old & 0x7fffffff) == 0 && prev >= 0)
>>> + if (old == 0 && __atomic_cmpxchg_bool(&rw->lock, old, old | 0x80000000))
>>> break;
>>> + smp_mb();
>>> }
>>> }
>>> EXPORT_SYMBOL(_raw_write_lock_wait);
>>>
>>> -#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */
>>> -
>>> int _raw_write_trylock_retry(arch_rwlock_t *rw)
>>> {
>>> int count = spin_retry;
>>>
>
More information about the kernel-team
mailing list