From patchwork Fri Nov 13 14:02:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 1399835 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=linutronix.de Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=f9dQOlOq; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=linutronix.de header.i=@linutronix.de header.a=rsa-sha256 header.s=2020 header.b=CaNkSgmH; dkim=fail reason="signature verification failed" header.d=linutronix.de header.i=@linutronix.de header.a=ed25519-sha256 header.s=2020e header.b=0cKyj2lL; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CXgnm3JGkz9s1l for ; Sat, 14 Nov 2020 01:29:00 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:Subject:To:From:Date: Message-Id:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:List-Owner; bh=i20y9BNWrQaKIn5m3XQjG/P9ID8ZUvKtCoTxmlpPVXY=; b=f9dQOlOqVppaU8wFLvZmoGLWR PSy+K+GUgq0bK8cbIFLTQlpuFic99zvqrYfKPXCt6J01w7eGLBDdOnr5oqawXD+mBBAifmHE9JR2f YqQTvtfIBStQ/3//Z7fUAXIlFUI2RcUP8rAAC38KImlZ5KaevphTrXJzev06pHWd7w6XUbnEnsKAl vniUlmRQ5MiOSnjsFhC8zqVZi04MmFhvjwxXTQPEmjdV5QmjNuXHuLP22hBkJuE/tyuJOXQPS/TBi Od3PKuUXwBoe1URvsP1roThLcrG4HW9IWA75k0RsgI5Yb+InDP2tSCHr5zDsbuaI/3b23ujEefqmx Dyr9kA3Lg==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kda4O-0000IJ-SU; Fri, 13 Nov 2020 14:28:56 +0000 Received: from galois.linutronix.de ([193.142.43.55]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kda0F-0006Q1-0O; Fri, 13 Nov 2020 14:24:48 +0000 Message-Id: <20201113141734.907075915@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1605277477; 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: content-transfer-encoding:content-transfer-encoding: references:references; bh=YBANw5+gKo0StNgfq2DAY2w568FUqe7IjvTxRxyhO0o=; b=CaNkSgmHOT8cChidgcipppyqnkXkMwbX36+aFt96F4A75TGeSz5Zhl+di5OltLmYsPtOcx quLDc5LLj6LblcQBRv5T8U2YTKstywSV4Fnr3VcKozPIF6fRJYoUQ1Olop/0XEo/nvWuKK AaWYWZNs1SHuSgrkR+sSNNUqkK/BZ+Mzqxcz+uw6LWxyeMfi7P4VPTLfGShWD5dSRZcvmV k6G5XKLQZrLBaSh78ZCTGlgHOMm+unqZIPu2euxm/TvxLdSaJIG/Ema0BvWrq4w4cjd3wq /o6/AEK8K3F6hkA6SrcnJ6gUpmrTkYW/8FpCsAN598OKXx8HQHBM1zasSFWkjA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1605277477; 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: content-transfer-encoding:content-transfer-encoding: references:references; bh=YBANw5+gKo0StNgfq2DAY2w568FUqe7IjvTxRxyhO0o=; b=0cKyj2lLbsO8b/2NxbYx+cHBAmiqLRZavh3aPgFuRABbFMMdYZx0eS73Lzn7tmtBZWlqdE UDGBXB070OjHFACQ== Date: Fri, 13 Nov 2020 15:02:26 +0100 From: Thomas Gleixner To: LKML Subject: [patch 19/19] tasklets: Prevent kill/unlock_wait deadlock on RT References: <20201113140207.499353218@linutronix.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20201113_092439_297708_B10E3F45 X-CRM114-Status: GOOD ( 16.78 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [193.142.43.55 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-um@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Marc Zyngier , Rich Felker , Catalin Marinas , Paul McKenney , Arnd Bergmann , linux-sh@vger.kernel.org, Peter Zijlstra , Richard Weinberger , Frederic Weisbecker , Valentin Schneider , Jeff Dike , Russell King , Yoshinori Sato , "James E.J. Bottomley" , linux-parisc@vger.kernel.org, Helge Deller , linux-um@lists.infradead.org, Will Deacon , Sebastian Andrzej Siewior , linux-arm-kernel@lists.infradead.org, Anton Ivanov Sender: "linux-um" Errors-To: linux-um-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org tasklet_kill() and tasklet_unlock_wait() spin and wait for the TASKLET_STATE_SCHED resp. TASKLET_STATE_RUN bit in the tasklet state to be cleared. This works on !RT nicely because the corresponding execution can only happen on a different CPU. On RT softirq processing is preemptible, therefore a task preempting the softirq processing thread can spin forever. Prevent this by invoking local_bh_disable()/enable() inside the loop. In case that the softirq processing thread was preempted by the current task, current will block on the local lock which yields the CPU to the preempted softirq processing thread. If the tasklet is processed on a different CPU then the local_bh_disable()/enable() pair is just a waste of processor cycles. Signed-off-by: Thomas Gleixner --- include/linux/interrupt.h | 8 ++------ kernel/softirq.c | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 7 deletions(-) --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -654,7 +654,7 @@ enum TASKLET_STATE_RUN /* Tasklet is running (SMP only) */ }; -#ifdef CONFIG_SMP +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT) static inline int tasklet_trylock(struct tasklet_struct *t) { return !test_and_set_bit(TASKLET_STATE_RUN, &(t)->state); @@ -666,11 +666,7 @@ static inline void tasklet_unlock(struct clear_bit(TASKLET_STATE_RUN, &(t)->state); } -static inline void tasklet_unlock_wait(struct tasklet_struct *t) -{ - while (test_bit(TASKLET_STATE_RUN, &(t)->state)) - cpu_relax(); -} +void tasklet_unlock_wait(struct tasklet_struct *t); #else static inline int tasklet_trylock(struct tasklet_struct *t) { return 1; } static inline void tasklet_unlock(struct tasklet_struct *t) { } --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -851,6 +851,29 @@ void tasklet_init(struct tasklet_struct } EXPORT_SYMBOL(tasklet_init); +#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT) + +void tasklet_unlock_wait(struct tasklet_struct *t) +{ + while (test_bit(TASKLET_STATE_RUN, &(t)->state)) { + if (IS_ENABLED(CONFIG_PREEMPT_RT)) { + /* + * Prevent a live lock when current preempted soft + * interrupt processing or prevents ksoftirqd from + * running. If the tasklet runs on a different CPU + * then this has no effect other than doing the BH + * disable/enable dance for nothing. + */ + local_bh_disable(); + local_bh_enable(); + } else { + cpu_relax(); + } + } +} +EXPORT_SYMBOL(tasklet_unlock_wait); +#endif + void tasklet_kill(struct tasklet_struct *t) { if (in_interrupt()) @@ -858,7 +881,20 @@ void tasklet_kill(struct tasklet_struct while (test_and_set_bit(TASKLET_STATE_SCHED, &t->state)) { do { - yield(); + if (IS_ENABLED(CONFIG_PREEMPT_RT)) { + /* + * Prevent a live lock when current + * preempted soft interrupt processing or + * prevents ksoftirqd from running. If the + * tasklet runs on a different CPU then + * this has no effect other than doing the + * BH disable/enable dance for nothing. + */ + local_bh_disable(); + local_bh_enable(); + } else { + yield(); + } } while (test_bit(TASKLET_STATE_SCHED, &t->state)); } tasklet_unlock_wait(t);