From patchwork Mon May 7 22:04:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Salisbury X-Patchwork-Id: 909949 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 40fxVG17xjz9s34; Tue, 8 May 2018 08:04:22 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1fFoEz-0001Xo-LR; Mon, 07 May 2018 22:04:17 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1fFoEx-0001XL-C5 for kernel-team@lists.ubuntu.com; Mon, 07 May 2018 22:04:15 +0000 Received: from 1.general.jsalisbury.us.vpn ([10.172.67.212] helo=salisbury) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.76) (envelope-from ) id 1fFoEw-0003CY-Ub for kernel-team@lists.ubuntu.com; Mon, 07 May 2018 22:04:15 +0000 Received: by salisbury (Postfix, from userid 1000) id CC0927E250C; Mon, 7 May 2018 18:04:13 -0400 (EDT) From: Joseph Salisbury To: kernel-team@lists.ubuntu.com Subject: [SRU][Xenial][PATCH 1/1] UBUNTU: SAUCE: (no-up) s390: fix rwlock implementation Date: Mon, 7 May 2018 18:04:13 -0400 Message-Id: <5619f9200cc002e3947b24dec43eff74c1f8e34d.1523284497.git.joseph.salisbury@canonical.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: References: In-Reply-To: References: X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Heiko Carstens 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: Heiko Carstens Signed-off-by: Joseph Salisbury Acked-by: Kleber Sacilotto de Souza Acked-by: Stefan Bader --- arch/s390/lib/spinlock.c | 48 +++++++++--------------------------------------- 1 file changed, 9 insertions(+), 39 deletions(-) diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 427aa44..99da25a 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c @@ -182,42 +182,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, unsigned int prev) -{ - unsigned int owner, old; - int count = spin_retry; - - owner = 0; - while (1) { - if (count-- <= 0) { - if (owner && !smp_vcpu_scheduled(~owner)) - smp_yield_cpu(~owner); - count = spin_retry; - } - old = ACCESS_ONCE(rw->lock); - owner = ACCESS_ONCE(rw->owner); - smp_mb(); - if ((int) old >= 0) { - prev = __RAW_LOCK(&rw->lock, 0x80000000, __RAW_OP_OR); - old = prev; - } - if ((old & 0x7fffffff) == 0 && (int) prev >= 0) - break; - if (MACHINE_HAS_CAD) - _raw_compare_and_delay(&rw->lock, old); - } -} -EXPORT_SYMBOL(_raw_write_lock_wait); - -#else /* CONFIG_HAVE_MARCH_Z196_FEATURES */ - +#else void _raw_write_lock_wait(arch_rwlock_t *rw) +#endif { - unsigned int owner, old, prev; + unsigned int owner, old; int count = spin_retry; - 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) { @@ -227,12 +203,8 @@ void _raw_write_lock_wait(arch_rwlock_t *rw) } old = ACCESS_ONCE(rw->lock); owner = ACCESS_ONCE(rw->owner); - if ((int) old >= 0 && - _raw_compare_and_swap(&rw->lock, old, old | 0x80000000)) - prev = old; - else - smp_mb(); - if ((old & 0x7fffffff) == 0 && (int) prev >= 0) + if (old == 0 && + _raw_compare_and_swap(&rw->lock, 0, 0x80000000)) break; if (MACHINE_HAS_CAD) _raw_compare_and_delay(&rw->lock, old); @@ -240,8 +212,6 @@ void _raw_write_lock_wait(arch_rwlock_t *rw) } EXPORT_SYMBOL(_raw_write_lock_wait); -#endif /* CONFIG_HAVE_MARCH_Z196_FEATURES */ - int _raw_write_trylock_retry(arch_rwlock_t *rw) { unsigned int old;