Received: by 2002:ac0:e350:0:0:0:0:0 with SMTP id g16csp778497imn; Sat, 30 Jul 2022 02:42:50 -0700 (PDT) X-Google-Smtp-Source: AGRyM1vTMAKgdN6t6WCfDDEzwupltCf7KlC/wZfr3lfJDWtd0cWwm6eA1kad6aAQ0uGuC3mmIRai X-Received: by 2002:a05:6402:5ca:b0:43b:6e01:482c with SMTP id n10-20020a05640205ca00b0043b6e01482cmr7328985edx.189.1659174170703; Sat, 30 Jul 2022 02:42:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659174170; cv=none; d=google.com; s=arc-20160816; b=EBTS/UdXJX6neXjOOgeJ+S8FURPDN+BKb/k29dpej71nNBFIM9LFT8wBaYkCsDj7tE uHM0/kNCf2J4g1VuI6zIBp3dh5XXKy0fgloyzywl+UeOXUMfXDib6PST6RDhVVX1OyQb FCG1dSH/o/p320RnBCDCtpK+z6UpVXfBpRSOAPzDt/5H8J9c6JmJnIXFK9CioMMY3ZBP 0JKtoYNogfos158wF9a+tUM/TwuHKEnOAhF6z0vq1uFINy06VmkIRv1lnfxt4kMMWVNF uFsnuWxNhoky6RJxZlnr9nxkWAdq1UDnO3rqUpDTD8uLv4bfJRbNYAlIYtE1OGAcMVZa wUEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:robot-unsubscribe :robot-id:message-id:mime-version:references:in-reply-to:cc:subject :to:reply-to:sender:from:dkim-signature:dkim-signature:date; bh=LeIxic/k3kF48XBgfzV0cYUall+6Yn4slRoomda4PTg=; b=vHzel6JHRK1VRFqETK8Z3ypjStH7SGvh+Tz2DlG5wI/5K0V+hruu2TCrtk6mH5zFkI +HzJKDyCKC2p14gGMLCEk6RhJCxBp+tXScN65o1m5PPiJnyPW36aWNkun8g9Mec8mWMU TlDOPOMJg7U1C+wmmdq3C2+zHj2cu+Maew6jVjAaXfII5KZekyakV0XO7gb+L9uPgznt okbOlkSBgqmkeOor0Cdy0wErXcO0Cyu0Mo3Rynq3NDE+TR/++vlJWVw64r2X1j66qW9D N73mgY62WEhFYSkbQTN6JdRJYzv9TpHMJNzSnf5ylRg9TTy8pzK8nNov6pO4WBrZGFLr CE8Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=aAIHYto0; dkim=neutral (no key) header.i=@linutronix.de header.b=KRksxc8i; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id bm19-20020a0564020b1300b0043cbacc60e0si2449985edb.388.2022.07.30.02.42.26; Sat, 30 Jul 2022 02:42:50 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=aAIHYto0; dkim=neutral (no key) header.i=@linutronix.de header.b=KRksxc8i; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233782AbiG3JgE (ORCPT + 99 others); Sat, 30 Jul 2022 05:36:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36942 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234587AbiG3Jf7 (ORCPT ); Sat, 30 Jul 2022 05:35:59 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 68DA618E37; Sat, 30 Jul 2022 02:35:58 -0700 (PDT) Date: Sat, 30 Jul 2022 09:35:54 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1659173756; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LeIxic/k3kF48XBgfzV0cYUall+6Yn4slRoomda4PTg=; b=aAIHYto0xIDQBS47rBx1ch0qDHMbCk+kUJ64QaHf2yrDHT0pZSLO841oEkgzGFQkuyodmm PMod66XwNiWSMDK8LFflP/9TdGEg1s15GEP2FD9ryvrNuN0x5lgumSbeYUOgU/uBHiJ/Gy T1H5hwBVzImcaZPB+US2kNgx7AqRe+8Qh0Idehxs6fHn1XosbuuGEqQDJhye8NAb3VG2tx aXJw40SYDe1TlO6lYFn1K0SUDTtFsO9EEHF0oAZ3dj4ykvQZL6Rr1MCeXVGfezQbRzvAL2 uJmjAdVJRTDVLfQS1gAKuVU4wROxwHllunj5DIR7atlqZAX7k1KrKuBqmkeCqw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1659173756; h=from:from:sender:sender:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LeIxic/k3kF48XBgfzV0cYUall+6Yn4slRoomda4PTg=; b=KRksxc8iwgZXbzqLZbfAF1Yr8rTMSPnvUiK0iIkqyWK3ChG7NhGj/x6K1oQ8FBIGTdkzXZ LE3aTCe8ezyL5CAA== From: "tip-bot2 for Waiman Long" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: locking/urgent] locking/rwsem: Allow slowpath writer to ignore handoff bit if not set by first waiter Cc: Waiman Long , "Peter Zijlstra (Intel)" , John Donnelly , Mel Gorman , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20220622200419.778799-1-longman@redhat.com> References: <20220622200419.778799-1-longman@redhat.com> MIME-Version: 1.0 Message-ID: <165917375432.15455.2614303631221531501.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The following commit has been merged into the locking/urgent branch of tip: Commit-ID: 6eebd5fb20838f5971ba17df9f55cc4f84a31053 Gitweb: https://git.kernel.org/tip/6eebd5fb20838f5971ba17df9f55cc4f84a31053 Author: Waiman Long AuthorDate: Wed, 22 Jun 2022 16:04:19 -04:00 Committer: Peter Zijlstra CommitterDate: Sat, 30 Jul 2022 10:58:28 +02:00 locking/rwsem: Allow slowpath writer to ignore handoff bit if not set by first waiter With commit d257cc8cb8d5 ("locking/rwsem: Make handoff bit handling more consistent"), the writer that sets the handoff bit can be interrupted out without clearing the bit if the wait queue isn't empty. This disables reader and writer optimistic lock spinning and stealing. Now if a non-first writer in the queue is somehow woken up or a new waiter enters the slowpath, it can't acquire the lock. This is not the case before commit d257cc8cb8d5 as the writer that set the handoff bit will clear it when exiting out via the out_nolock path. This is less efficient as the busy rwsem stays in an unlock state for a longer time. In some cases, this new behavior may cause lockups as shown in [1] and [2]. This patch allows a non-first writer to ignore the handoff bit if it is not originally set or initiated by the first waiter. This patch is shown to be effective in fixing the lockup problem reported in [1]. [1] https://lore.kernel.org/lkml/20220617134325.GC30825@techsingularity.net/ [2] https://lore.kernel.org/lkml/3f02975c-1a9d-be20-32cf-f1d8e3dfafcc@oracle.com/ Fixes: d257cc8cb8d5 ("locking/rwsem: Make handoff bit handling more consistent") Signed-off-by: Waiman Long Signed-off-by: Peter Zijlstra (Intel) Acked-by: John Donnelly Tested-by: Mel Gorman Link: https://lore.kernel.org/r/20220622200419.778799-1-longman@redhat.com --- kernel/locking/rwsem.c | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 9d1db4a..65f0262 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -335,8 +335,6 @@ struct rwsem_waiter { struct task_struct *task; enum rwsem_waiter_type type; unsigned long timeout; - - /* Writer only, not initialized in reader */ bool handoff_set; }; #define rwsem_first_waiter(sem) \ @@ -459,10 +457,12 @@ static void rwsem_mark_wake(struct rw_semaphore *sem, * to give up the lock), request a HANDOFF to * force the issue. */ - if (!(oldcount & RWSEM_FLAG_HANDOFF) && - time_after(jiffies, waiter->timeout)) { - adjustment -= RWSEM_FLAG_HANDOFF; - lockevent_inc(rwsem_rlock_handoff); + if (time_after(jiffies, waiter->timeout)) { + if (!(oldcount & RWSEM_FLAG_HANDOFF)) { + adjustment -= RWSEM_FLAG_HANDOFF; + lockevent_inc(rwsem_rlock_handoff); + } + waiter->handoff_set = true; } atomic_long_add(-adjustment, &sem->count); @@ -599,7 +599,7 @@ rwsem_del_wake_waiter(struct rw_semaphore *sem, struct rwsem_waiter *waiter, static inline bool rwsem_try_write_lock(struct rw_semaphore *sem, struct rwsem_waiter *waiter) { - bool first = rwsem_first_waiter(sem) == waiter; + struct rwsem_waiter *first = rwsem_first_waiter(sem); long count, new; lockdep_assert_held(&sem->wait_lock); @@ -609,11 +609,20 @@ static inline bool rwsem_try_write_lock(struct rw_semaphore *sem, bool has_handoff = !!(count & RWSEM_FLAG_HANDOFF); if (has_handoff) { - if (!first) + /* + * Honor handoff bit and yield only when the first + * waiter is the one that set it. Otherwisee, we + * still try to acquire the rwsem. + */ + if (first->handoff_set && (waiter != first)) return false; - /* First waiter inherits a previously set handoff bit */ - waiter->handoff_set = true; + /* + * First waiter can inherit a previously set handoff + * bit and spin on rwsem if lock acquisition fails. + */ + if (waiter == first) + waiter->handoff_set = true; } new = count; @@ -1027,6 +1036,7 @@ queue: waiter.task = current; waiter.type = RWSEM_WAITING_FOR_READ; waiter.timeout = jiffies + RWSEM_WAIT_TIMEOUT; + waiter.handoff_set = false; raw_spin_lock_irq(&sem->wait_lock); if (list_empty(&sem->wait_list)) {