Skip to content

Commit ed00495

Browse files
peterz@infradead.orgIngo Molnar
authored andcommitted
locking/lockdep: Fix TRACE_IRQFLAGS vs. NMIs
Prior to commit: 859d069 ("lockdep: Prepare for NMI IRQ state tracking") IRQ state tracking was disabled in NMIs due to nmi_enter() doing lockdep_off() -- with the obvious requirement that NMI entry call nmi_enter() before trace_hardirqs_off(). [ AFAICT, PowerPC and SH violate this order on their NMI entry ] However, that commit explicitly changed lockdep_hardirqs_*() to ignore lockdep_off() and breaks every architecture that has irq-tracing in it's NMI entry that hasn't been fixed up (x86 being the only fixed one at this point). The reason for this change is that by ignoring lockdep_off() we can: - get rid of 'current->lockdep_recursion' in lockdep_assert_irqs*() which was going to to give header-recursion issues with the seqlock rework. - allow these lockdep_assert_*() macros to function in NMI context. Restore the previous state of things and allow an architecture to opt-in to the NMI IRQ tracking support, however instead of relying on lockdep_off(), rely on in_nmi(), both are part of nmi_enter() and so over-all entry ordering doesn't need to change. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent ba1f2b2 commit ed00495

File tree

3 files changed

+16
-1
lines changed

3 files changed

+16
-1
lines changed

arch/x86/Kconfig.debug

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
config TRACE_IRQFLAGS_SUPPORT
44
def_bool y
55

6+
config TRACE_IRQFLAGS_NMI_SUPPORT
7+
def_bool y
8+
69
config EARLY_PRINTK_USB
710
bool
811

kernel/locking/lockdep.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3712,6 +3712,9 @@ void noinstr lockdep_hardirqs_on(unsigned long ip)
37123712
* and not rely on hardware state like normal interrupts.
37133713
*/
37143714
if (unlikely(in_nmi())) {
3715+
if (!IS_ENABLED(CONFIG_TRACE_IRQFLAGS_NMI))
3716+
return;
3717+
37153718
/*
37163719
* Skip:
37173720
* - recursion check, because NMI can hit lockdep;
@@ -3773,7 +3776,10 @@ void noinstr lockdep_hardirqs_off(unsigned long ip)
37733776
* they will restore the software state. This ensures the software
37743777
* state is consistent inside NMIs as well.
37753778
*/
3776-
if (unlikely(!in_nmi() && (current->lockdep_recursion & LOCKDEP_RECURSION_MASK)))
3779+
if (in_nmi()) {
3780+
if (!IS_ENABLED(CONFIG_TRACE_IRQFLAGS_NMI))
3781+
return;
3782+
} else if (current->lockdep_recursion & LOCKDEP_RECURSION_MASK)
37773783
return;
37783784

37793785
/*

lib/Kconfig.debug

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,11 +1325,17 @@ config WW_MUTEX_SELFTEST
13251325
endmenu # lock debugging
13261326

13271327
config TRACE_IRQFLAGS
1328+
depends on TRACE_IRQFLAGS_SUPPORT
13281329
bool
13291330
help
13301331
Enables hooks to interrupt enabling and disabling for
13311332
either tracing or lock debugging.
13321333

1334+
config TRACE_IRQFLAGS_NMI
1335+
def_bool y
1336+
depends on TRACE_IRQFLAGS
1337+
depends on TRACE_IRQFLAGS_NMI_SUPPORT
1338+
13331339
config STACKTRACE
13341340
bool "Stack backtrace support"
13351341
depends on STACKTRACE_SUPPORT

0 commit comments

Comments
 (0)