From: Steven Rostedt <rostedt@goodmis.org>
To: linux-kernel@vger.kernel.org,
linux-rt-users <linux-rt-users@vger.kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>,
Carsten Emde <C.Emde@osadl.org>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
John Kacur <jkacur@redhat.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Linus Torvalds <torvalds@linux-foundation.org>,
Andrew Morton <akpm@linux-foundation.org>,
Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@kernel.org>
Subject: [PATCH RT 3/5] lockdep: Correctly annotate hardirq context in irq_exit()
Date: Tue, 10 Dec 2013 19:37:35 -0500 [thread overview]
Message-ID: <20131211003801.986511386@goodmis.org> (raw)
In-Reply-To: 20131211003732.351606520@goodmis.org
[-- Attachment #1: 0003-lockdep-Correctly-annotate-hardirq-context-in-irq_ex.patch --]
[-- Type: text/plain, Size: 4266 bytes --]
3.10.22-rt20-rc1 stable review patch.
If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <peterz@infradead.org>
There was a reported deadlock on -rt which lockdep didn't report.
It turns out that in irq_exit() we tell lockdep that the hardirq
context ends and then do all kinds of locking afterwards.
To fix it, move trace_hardirq_exit() to the very end of irq_exit(), this
ensures all locking in tick_irq_exit() and rcu_irq_exit() are properly
recorded as happening from hardirq context.
This however leads to the 'fun' little problem of running softirqs
while in hardirq context. To cure this make the softirq code a little
more complex (in the CONFIG_TRACE_IRQFLAGS case).
Due to stack swizzling arch dependent trickery we cannot pass an
argument to __do_softirq() to tell it if it was done from hardirq
context or not; so use a side-band argument.
When we do __do_softirq() from hardirq context, 'atomically' flip to
softirq context and back, so that no locking goes without being in
either hard- or soft-irq context.
I didn't find any new problems in mainline using this patch, but it
did show the -rt problem.
Cc: stable-rt@vger.kernel.org
Reported-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/n/tip-dgwc5cdksbn0jk09vbmcc9sa@git.kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
---
kernel/softirq.c | 46 ++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 42 insertions(+), 4 deletions(-)
diff --git a/kernel/softirq.c b/kernel/softirq.c
index 4cacbcd..541adf3 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -355,6 +355,44 @@ EXPORT_SYMBOL(local_bh_enable_ip);
#define MAX_SOFTIRQ_TIME msecs_to_jiffies(2)
#define MAX_SOFTIRQ_RESTART 10
+#ifdef CONFIG_TRACE_IRQFLAGS
+/*
+ * Convoluted means of passing __do_softirq() a message through the various
+ * architecture execute_on_stack() bits.
+ *
+ * When we run softirqs from irq_exit() and thus on the hardirq stack we need
+ * to keep the lockdep irq context tracking as tight as possible in order to
+ * not miss-qualify lock contexts and miss possible deadlocks.
+ */
+static DEFINE_PER_CPU(int, softirq_from_hardirq);
+
+static inline void lockdep_softirq_from_hardirq(void)
+{
+ this_cpu_write(softirq_from_hardirq, 1);
+}
+
+static inline void lockdep_softirq_start(void)
+{
+ if (this_cpu_read(softirq_from_hardirq))
+ trace_hardirq_exit();
+ lockdep_softirq_enter();
+}
+
+static inline void lockdep_softirq_end(void)
+{
+ lockdep_softirq_exit();
+ if (this_cpu_read(softirq_from_hardirq)) {
+ this_cpu_write(softirq_from_hardirq, 0);
+ trace_hardirq_enter();
+ }
+}
+
+#else
+static inline void lockdep_softirq_from_hardirq(void) { }
+static inline void lockdep_softirq_start(void) { }
+static inline void lockdep_softirq_end(void) { }
+#endif
+
asmlinkage void __do_softirq(void)
{
__u32 pending;
@@ -375,7 +413,7 @@ asmlinkage void __do_softirq(void)
__local_bh_disable((unsigned long)__builtin_return_address(0),
SOFTIRQ_OFFSET);
- lockdep_softirq_enter();
+ lockdep_softirq_start();
cpu = smp_processor_id();
restart:
@@ -393,8 +431,7 @@ restart:
wakeup_softirqd();
}
- lockdep_softirq_exit();
-
+ lockdep_softirq_end();
account_irq_exit_time(current);
__local_bh_enable(SOFTIRQ_OFFSET);
tsk_restore_flags(current, old_flags, PF_MEMALLOC);
@@ -700,6 +737,7 @@ static inline void invoke_softirq(void)
{
#ifndef CONFIG_PREEMPT_RT_FULL
if (!force_irqthreads) {
+ lockdep_softirq_from_hardirq();
/*
* We can safely execute softirq on the current stack if
* it is the irq stack, because it should be near empty
@@ -749,13 +787,13 @@ void irq_exit(void)
#endif
account_irq_exit_time(current);
- trace_hardirq_exit();
sub_preempt_count(HARDIRQ_OFFSET);
if (!in_interrupt() && local_softirq_pending())
invoke_softirq();
tick_irq_exit();
rcu_irq_exit();
+ trace_hardirq_exit(); /* must be last! */
}
void raise_softirq(unsigned int nr)
--
1.8.4.3
next prev parent reply other threads:[~2013-12-11 0:38 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-11 0:37 [PATCH RT 0/5] Linux 3.10.22-rt20-rc1 Steven Rostedt
2013-12-11 0:37 ` [PATCH RT 1/5] cpu_down: move migrate_enable() back Steven Rostedt
2013-12-11 0:37 ` [PATCH RT 2/5] a few open coded completions Steven Rostedt
2013-12-11 14:25 ` Corey Minyard
2013-12-11 15:34 ` Steven Rostedt
2013-12-15 15:28 ` Sebastian Andrzej Siewior
2013-12-15 21:08 ` Steven Rostedt
2013-12-11 19:49 ` Steven Rostedt
2014-03-09 0:27 ` Ben Hutchings
2014-03-10 14:29 ` Steven Rostedt
2014-03-10 17:52 ` Ben Hutchings
2014-03-10 18:14 ` Steven Rostedt
2014-03-11 2:06 ` Ben Hutchings
2014-03-11 2:56 ` Steven Rostedt
2014-03-11 15:54 ` Steven Rostedt
2014-03-12 18:15 ` Ben Hutchings
2013-12-11 0:37 ` Steven Rostedt [this message]
2013-12-11 0:37 ` [PATCH RT 4/5] rtmutex: use a trylock for waiter lock in trylock Steven Rostedt
2013-12-11 0:37 ` [PATCH RT 5/5] Linux 3.10.22-rt20-rc1 Steven Rostedt
-- strict thread matches above, loose matches on Subject: below --
2013-12-11 0:46 [PATCH RT 0/5] Linux 3.8.13.13-rt26-rc1 Steven Rostedt
2013-12-11 0:46 ` [PATCH RT 3/5] lockdep: Correctly annotate hardirq context in irq_exit() Steven Rostedt
2013-12-11 0:50 [PATCH RT 0/5] Linux 3.4.72-rt90-rc1 Steven Rostedt
2013-12-11 0:50 ` [PATCH RT 3/5] lockdep: Correctly annotate hardirq context in irq_exit() Steven Rostedt
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=20131211003801.986511386@goodmis.org \
--to=rostedt@goodmis.org \
--cc=C.Emde@osadl.org \
--cc=akpm@linux-foundation.org \
--cc=bigeasy@linutronix.de \
--cc=fweisbec@gmail.com \
--cc=jkacur@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-users@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.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.