From 6772faa1ba22eba18d087c2459030a683b65be57 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 5 Jun 2013 17:58:20 +0000 Subject: [PATCH] powerpc/perf: Fix deadlock caused by calling printk() in PMU exception In commit bc09c21 "Fix finding overflowed PMC in interrupt" we added a printk() to the PMU exception handler. Unfortunately that is not safe. The problem is that the PMU exception may run even when interrupts are soft disabled, aka NMI context. We do this so that we can profile parts of the kernel that have interrupts soft-disabled. But by calling printk() from the exception handler, we can potentially deadlock in the printk code on logbuf_lock, eg: [c00000038ba575c0] c000000000081928 .vprintk_emit+0xa8/0x540 [c00000038ba576a0] c0000000007bcde8 .printk+0x48/0x58 [c00000038ba57710] c000000000076504 .perf_event_interrupt+0x2d4/0x490 [c00000038ba57810] c00000000001f6f8 .performance_monitor_exception+0x48/0x60 [c00000038ba57880] c0000000000032cc performance_monitor_common+0x14c/0x180 --- Exception: f01 (Performance Monitor) at c0000000007b25d4 ._raw_spin_lock_irq +0x64/0xc0 [c00000038ba57bf0] c00000000007ed90 .devkmsg_read+0xd0/0x5a0 [c00000038ba57d00] c0000000001c2934 .vfs_read+0xc4/0x1e0 [c00000038ba57d90] c0000000001c2cd8 .SyS_read+0x58/0xd0 [c00000038ba57e30] c000000000009d54 syscall_exit+0x0/0x98 --- Exception: c01 (System Call) at 00001fffffbf6f7c SP (3ffff6d4de10) is in userspace Fix it by making sure we only call printk() when we are not in NMI context. Signed-off-by: Michael Ellerman Cc: # 3.9 Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/perf/core-book3s.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c index 845c867444e6..29c6482890c8 100644 --- a/arch/powerpc/perf/core-book3s.c +++ b/arch/powerpc/perf/core-book3s.c @@ -1758,7 +1758,7 @@ static void perf_event_interrupt(struct pt_regs *regs) } } } - if ((!found) && printk_ratelimit()) + if (!found && !nmi && printk_ratelimit()) printk(KERN_WARNING "Can't find PMC that caused IRQ\n"); /*