All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Frederic Weisbecker <frederic@kernel.org>,
	Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
	"Ahmed S. Darwish" <a.darwish@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	Denis Kirjanov <kda@linux-powerpc.org>,
	"David S. Miller" <davem@davemloft.net>,
	Jakub Kicinski <kuba@kernel.org>,
	netdev@vger.kernel.org, ath9k-devel@qca.qualcomm.com,
	Kalle Valo <kvalo@codeaurora.org>,
	linux-wireless@vger.kernel.org, Chas Williams <3chas3@gmail.com>,
	linux-atm-general@lists.sourceforge.net,
	"K. Y. Srinivasan" <kys@microsoft.com>,
	Haiyang Zhang <haiyangz@microsoft.com>,
	Stephen Hemminger <sthemmin@microsoft.com>,
	Wei Liu <wei.liu@kernel.org>,
	Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
	Rob Herring <robh@kernel.org>,
	Bjorn Helgaas <bhelgaas@google.com>,
	linux-hyperv@vger.kernel.org, linux-pci@vger.kernel.org,
	Stefan Richter <stefanr@s5r6.in-berlin.de>,
	linux1394-devel@lists.sourceforge.net
Subject: [patch 07/14] tasklets: Prevent tasklet_unlock_spin_wait() deadlock on RT
Date: Tue, 09 Mar 2021 09:42:10 +0100	[thread overview]
Message-ID: <20210309084241.988908275@linutronix.de> (raw)
In-Reply-To: 20210309084203.995862150@linutronix.de

tasklet_unlock_spin_wait() spin waits for the TASKLET_STATE_SCHED 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 <tglx@linutronix.de>
Tested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
 include/linux/interrupt.h |    2 +-
 kernel/softirq.c          |   28 +++++++++++++++++++++++++++-
 2 files changed, 28 insertions(+), 2 deletions(-)

--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -658,7 +658,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);
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -616,6 +616,32 @@ void tasklet_init(struct tasklet_struct
 }
 EXPORT_SYMBOL(tasklet_init);
 
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
+/*
+ * Do not use in new code. There is no real reason to invoke this from
+ * atomic contexts.
+ */
+void tasklet_unlock_spin_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_spin_wait);
+#endif
+
 void tasklet_kill(struct tasklet_struct *t)
 {
 	if (in_interrupt())
@@ -629,7 +655,7 @@ void tasklet_kill(struct tasklet_struct
 }
 EXPORT_SYMBOL(tasklet_kill);
 
-#ifdef CONFIG_SMP
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT_RT)
 void tasklet_unlock(struct tasklet_struct *t)
 {
 	smp_mb__before_atomic();


  parent reply	other threads:[~2021-03-09  8:46 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-09  8:42 [patch 00/14] tasklets: Replace the spin wait loops and make it RT safe Thomas Gleixner
2021-03-09  8:42 ` [patch 01/14] tasklets: Replace barrier() with cpu_relax() in tasklet_unlock_wait() Thomas Gleixner
2021-03-17 15:49   ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2021-03-09  8:42 ` [patch 02/14] tasklets: Use static inlines for stub implementations Thomas Gleixner
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2021-03-09  8:42 ` [patch 03/14] tasklets: Provide tasklet_disable_in_atomic() Thomas Gleixner
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2021-03-09  8:42 ` [patch 04/14] tasklets: Use spin wait in tasklet_disable() temporarily Thomas Gleixner
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2021-03-09  8:42 ` [patch 05/14] tasklets: Replace spin wait in tasklet_unlock_wait() Thomas Gleixner
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Peter Zijlstra
2021-03-09  8:42 ` [patch 06/14] tasklets: Replace spin wait in tasklet_kill() Thomas Gleixner
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Peter Zijlstra
2021-03-09  8:42 ` Thomas Gleixner [this message]
2021-03-09 15:00   ` [patch 07/14] tasklets: Prevent tasklet_unlock_spin_wait() deadlock on RT Sebastian Andrzej Siewior
2021-03-09 15:21     ` Sebastian Andrzej Siewior
2021-03-10  8:35       ` Thomas Gleixner
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2021-03-09  8:42 ` [patch 08/14] net: jme: Replace link-change tasklet with work Thomas Gleixner
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Sebastian Andrzej Siewior
2021-03-09  8:42 ` [patch 09/14] net: sundance: Use tasklet_disable_in_atomic() Thomas Gleixner
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Sebastian Andrzej Siewior
2021-03-09  8:42 ` [patch 10/14] ath9k: " Thomas Gleixner
2021-03-09 10:23   ` Kalle Valo
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Sebastian Andrzej Siewior
2021-03-09  8:42 ` [patch 11/14] atm: eni: Use tasklet_disable_in_atomic() in the send() callback Thomas Gleixner
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Sebastian Andrzej Siewior
2021-03-09  8:42 ` [patch 12/14] PCI: hv: Use tasklet_disable_in_atomic() Thomas Gleixner
2021-03-09 22:17   ` Bjorn Helgaas
2021-03-10 11:34   ` Wei Liu
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Sebastian Andrzej Siewior
2021-03-09  8:42 ` [patch 13/14] firewire: ohci: Use tasklet_disable_in_atomic() where required Thomas Gleixner
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Sebastian Andrzej Siewior
2021-03-09  8:42 ` [patch 14/14] tasklets: Switch tasklet_disable() to the sleep wait variant Thomas Gleixner
2021-03-17 15:48   ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2021-03-09 14:04 ` [patch 00/14] tasklets: Replace the spin wait loops and make it RT safe Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210309084241.988908275@linutronix.de \
    --to=tglx@linutronix.de \
    --cc=3chas3@gmail.com \
    --cc=a.darwish@linutronix.de \
    --cc=ath9k-devel@qca.qualcomm.com \
    --cc=bhelgaas@google.com \
    --cc=bigeasy@linutronix.de \
    --cc=davem@davemloft.net \
    --cc=frederic@kernel.org \
    --cc=haiyangz@microsoft.com \
    --cc=kda@linux-powerpc.org \
    --cc=kuba@kernel.org \
    --cc=kvalo@codeaurora.org \
    --cc=kys@microsoft.com \
    --cc=linux-atm-general@lists.sourceforge.net \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linux1394-devel@lists.sourceforge.net \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=netdev@vger.kernel.org \
    --cc=peterz@infradead.org \
    --cc=robh@kernel.org \
    --cc=stefanr@s5r6.in-berlin.de \
    --cc=sthemmin@microsoft.com \
    --cc=wei.liu@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.