From patchwork Wed Mar 22 16:27:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sebastian Andrzej Siewior X-Patchwork-Id: 73518 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:604a:0:0:0:0:0 with SMTP id j10csp2438344wrt; Wed, 22 Mar 2023 09:33:22 -0700 (PDT) X-Google-Smtp-Source: AK7set/Pp1yg4IochkkRnB6YsZSiFNps8HfcsRPOkvgrbdJYr2sgw1mrRxKyYVvzLYEJ/z7JdHRR X-Received: by 2002:a05:6a20:354a:b0:cb:98e5:de2c with SMTP id f10-20020a056a20354a00b000cb98e5de2cmr241220pze.8.1679502802359; Wed, 22 Mar 2023 09:33:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679502802; cv=none; d=google.com; s=arc-20160816; b=VcopOUtTD9aiZyCGyzsLgyw0jYNhUpTOS+a3ZmIc8Lm+5eSZ0H0w3g2kGmnv8eGZ5k Vx75QXukYhH5cF0XXnTWi84Pf8UtWgkZQ52pRxhUmE1P8dSMFuZc/qFLMQ93gKR4jyKY 74Lnm/yI0ki6nXJHj2DScL9ddTKo+d4Z+9A5pXw5EDoF0mqXMzXb6i05rsZm2j7scZgG /CCiDANBo5MEvd/vRyxQtQ67CJ1w4ldfgODN7LZcsF+DPCSzaaxj1DDow5LmeIVvOVIR 2A6W4ODS//Knfj4ucTQbEfMs1GxwX0mA5xDfJvQGerKjEibJUyOqBl8xjId/Y11tGseR TJSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-disposition:mime-version:message-id :subject:cc:to:from:dkim-signature:dkim-signature:date; bh=9Rm915zahe3wkfDA3OoSR/L3qpm80GrhS/bMurOPXUw=; b=hUiBStrSfHJEyZ8y6fsr2z+uDpJMEUick7ORd4H37zEksgqcZAgRHovIGFIpBrvE0a sOt7GPM5HMDsQodkBkYdCwFV2YDdmJgFe66xu5GbUsQ2Wp95hhAl6o/YQxEERn2VXfRu TsucmSUanQBxnwesfSn621atrRAqaNvdwed+In+biPXE1ImZfIP8zRnwdu4wXD31DaDs yGhckGee57MUnnIJsKnaQVIZmNutxbjkqeCzF4nIN6/0I/aD0cxtzleViUn2M+eXVaLk +J89HfmGgGrXFGr09l/bRqE6fgD4wsrHFoz9lo0kpr2jATXE9Ob1Jr+5EI9qtbwgPI9h WXIw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=gJD8resC; dkim=neutral (no key) header.i=@linutronix.de; 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: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j6-20020a056a00130600b00627e8281621si11804121pfu.130.2023.03.22.09.33.08; Wed, 22 Mar 2023 09:33:22 -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=gJD8resC; dkim=neutral (no key) header.i=@linutronix.de; 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 S230110AbjCVQ1t (ORCPT + 99 others); Wed, 22 Mar 2023 12:27:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59670 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229788AbjCVQ1n (ORCPT ); Wed, 22 Mar 2023 12:27:43 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D36C660D7E for ; Wed, 22 Mar 2023 09:27:23 -0700 (PDT) Date: Wed, 22 Mar 2023 17:27:19 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1679502441; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type; bh=9Rm915zahe3wkfDA3OoSR/L3qpm80GrhS/bMurOPXUw=; b=gJD8resC1Fv1HxTm3TwZdZQqtLtBZkthWZGKGNlHWKbcAfflfIJgktQ0dLbUiGo/TuIyrx rYRvAfkHk3wjk340s8bMIXiXdbbTEEHS2eDzk3VqeoDOvqnOnU9aWn7bW66AfL1LZQPnxc anjx0PS6Lo9GZ4BbSiPiicx174egLrRxeHTV/UC0UngW7loYP8997KJ9zJ/AXzYSt+sCK2 bzGLXGP2IlUUXtCt25A7MZdeKEyT5ZZJHGMja/nOuOUZXKWm+6+telYXU8EZiJZRX/XkdT VvwrgBrxgPha31sTucOiY1uNEeUkwLwhwBMSoNjhmDS4RtGBIKrM1EiAcMKOMg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1679502441; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type; bh=9Rm915zahe3wkfDA3OoSR/L3qpm80GrhS/bMurOPXUw=; b=xiaieJyN/TwkmbQDmpGFACCEw+FEWUcM2mYF2MOK/zHj4RgxKhdi5ULkvybRSRbfZ5+g9d aU2xtawMQ9yOGjCw== From: Sebastian Andrzej Siewior To: Thomas Gleixner , linux-kernel@vger.kernel.org Cc: Crystal Wood , John Keeping , Boqun Feng , Ingo Molnar , Peter Zijlstra , Waiman Long , Will Deacon Subject: [PATCH] locking/rtmutex: Flush the plug before entering the slowpath. Message-ID: <20230322162719.wYG1N0hh@linutronix.de> MIME-Version: 1.0 Content-Disposition: inline X-Spam-Status: No, score=-2.5 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED autolearn=unavailable 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 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1761086330301756528?= X-GMAIL-MSGID: =?utf-8?q?1761086330301756528?= blk_flush_plug() is invoked on schedule() to flush out the IO progress that has been made so far so that it is globally visible. This is important to avoid deadlocks because a lock owner can wait for IO. Therefore the IO must be first flushed before a thread can block on a lock. The plug flush routine can acquire a sleeping lock which is contended. Blocking on a lock requires an assignment to task_struct::pi_blocked_on. If blk_flush_plug() is invoked from the slow path on schedule() then the variable is already set and will be overwritten by the lock in blk_flush_plug(). Therefore it is needed to invoke blk_flush_plug() (and block on potential locks in the process) before the blocking on the actual lock. Invoke blk_flush_plug() before blocking on a sleeping lock. The PREEMPT_RT only sleeping locks (spinlock_t and rwlock_t) are excluded because their slow path does not invoke blk_flush_plug(). Fixes: e17ba59b7e8e1 ("locking/rtmutex: Guard regular sleeping locks specific functions") Reported-by: Crystal Wood Link: https://lore.kernel.org/4b4ab374d3e24e6ea8df5cadc4297619a6d945af.camel@redhat.com Signed-off-by: Sebastian Andrzej Siewior --- On 2023-02-20 19:21:51 [+0100], Thomas Gleixner wrote: > > This still leaves the problem vs. io_wq_worker_sleeping() and it's > running() counterpart after schedule(). io_wq_worker_sleeping() has a kfree() so it probably should be moved, too. io_wq_worker_running() is a OR and INC and is fine. > Aside of that for CONFIG_DEBUG_RT_MUTEXES=y builds it flushes on every > lock operation whether the lock is contended or not. For mutex & ww_mutex operations. rwsem is not affected by CONFIG_DEBUG_RT_MUTEXES. As for mutex it could be mitigated by invoking try_to_take_rt_mutex() before blk_flush_plug(). kernel/locking/rtmutex.c | 7 +++++++ kernel/locking/rwbase_rt.c | 8 ++++++++ kernel/locking/ww_rt_mutex.c | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c index 728f434de2bbf..c1bc2cb1522cb 100644 --- a/kernel/locking/rtmutex.c +++ b/kernel/locking/rtmutex.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -1700,6 +1701,12 @@ static __always_inline int __rt_mutex_lock(struct rt_mutex_base *lock, if (likely(rt_mutex_cmpxchg_acquire(lock, NULL, current))) return 0; + /* + * If we are going to sleep and we have plugged IO queued, make sure to + * submit it to avoid deadlocks. + */ + blk_flush_plug(current->plug, true); + return rt_mutex_slowlock(lock, NULL, state); } #endif /* RT_MUTEX_BUILD_MUTEX */ diff --git a/kernel/locking/rwbase_rt.c b/kernel/locking/rwbase_rt.c index c201aadb93017..70c08ec4ad8af 100644 --- a/kernel/locking/rwbase_rt.c +++ b/kernel/locking/rwbase_rt.c @@ -143,6 +143,14 @@ static __always_inline int rwbase_read_lock(struct rwbase_rt *rwb, if (rwbase_read_trylock(rwb)) return 0; + if (state != TASK_RTLOCK_WAIT) { + /* + * If we are going to sleep and we have plugged IO queued, + * make sure to submit it to avoid deadlocks. + */ + blk_flush_plug(current->plug, true); + } + return __rwbase_read_lock(rwb, state); } diff --git a/kernel/locking/ww_rt_mutex.c b/kernel/locking/ww_rt_mutex.c index d1473c624105c..472e3622abf09 100644 --- a/kernel/locking/ww_rt_mutex.c +++ b/kernel/locking/ww_rt_mutex.c @@ -67,6 +67,11 @@ __ww_rt_mutex_lock(struct ww_mutex *lock, struct ww_acquire_ctx *ww_ctx, ww_mutex_set_context_fastpath(lock, ww_ctx); return 0; } + /* + * If we are going to sleep and we have plugged IO queued, make sure to + * submit it to avoid deadlocks. + */ + blk_flush_plug(current->plug, true); ret = rt_mutex_slowlock(&rtm->rtmutex, ww_ctx, state);