Patchwork [3.5.y.z,extended,stable] Patch "panic: fix a possible deadlock in panic()" has been added to staging queue

mail settings
Submitter Luis Henriques
Date April 11, 2013, 9:09 a.m.
Message ID <>
Download mbox | patch
Permalink /patch/235632/
State New
Headers show


Luis Henriques - April 11, 2013, 9:09 a.m.
This is a note to let you know that I have just added a patch titled

    panic: fix a possible deadlock in panic()

to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree 
which can be found at:;a=shortlog;h=refs/heads/linux-3.5.y-queue

If you, or anyone else, feels it should not be added to this tree, please 
reply to this email.

For more information about the 3.5.y.z tree, see



From c481d1cb9d502679d1ce6d7334729340f55ec595 Mon Sep 17 00:00:00 2001
From: Vikram Mulukutla <>
Date: Mon, 30 Jul 2012 14:39:58 -0700
Subject: [PATCH] panic: fix a possible deadlock in panic()

commit 190320c3b6640d4104650f55ff69611e050ea06b upstream.

panic_lock is meant to ensure that panic processing takes place only on
one cpu; if any of the other cpus encounter a panic, they will spin
waiting to be shut down.

However, this causes a regression in this scenario:

1. Cpu 0 encounters a panic and acquires the panic_lock
   and proceeds with the panic processing.
2. There is an interrupt on cpu 0 that also encounters
   an error condition and invokes panic.
3. This second invocation fails to acquire the panic_lock
   and enters the infinite while loop in panic_smp_self_stop.

Thus all panic processing is stopped, and the cpu is stuck for eternity
in the while(1) inside panic_smp_self_stop.

To address this, disable local interrupts with local_irq_disable before
acquiring the panic_lock.  This will prevent interrupt handlers from
executing during the panic processing, thus avoiding this particular

Signed-off-by: Vikram Mulukutla <>
Reviewed-by: Stephen Boyd <>
Cc: Michael Holzheu <>
Signed-off-by: Andrew Morton <>
Signed-off-by: Linus Torvalds <>
Signed-off-by: Luis Henriques <>
 kernel/panic.c | 8 ++++++++
 1 file changed, 8 insertions(+)



diff --git a/kernel/panic.c b/kernel/panic.c
index d2a5f4e..e1b2822 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -75,6 +75,14 @@  void panic(const char *fmt, ...)
 	int state = 0;

+	 * Disable local interrupts. This will prevent panic_smp_self_stop
+	 * from deadlocking the first cpu that invokes the panic, since
+	 * there is nothing to prevent an interrupt handler (that runs
+	 * after the panic_lock is acquired) from invoking panic again.
+	 */
+	local_irq_disable();
+	/*
 	 * It's possible to come here directly from a panic-assertion and
 	 * not have preempt disabled. Some functions called from here want
 	 * preempt to be disabled. No point enabling it later though...