aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 405697a9f4d9..1f3159eb1ede 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -49,6 +49,7 @@
49#include <linux/poll.h> 49#include <linux/poll.h>
50#include <linux/string.h> 50#include <linux/string.h>
51#include <linux/ctype.h> 51#include <linux/ctype.h>
52#include <asm/atomic.h>
52#ifdef CONFIG_X86_LOCAL_APIC 53#ifdef CONFIG_X86_LOCAL_APIC
53#include <asm/apic.h> 54#include <asm/apic.h>
54#endif 55#endif
@@ -295,6 +296,8 @@ static int ipmi_start_timer_on_heartbeat = 0;
295static unsigned char ipmi_version_major; 296static unsigned char ipmi_version_major;
296static unsigned char ipmi_version_minor; 297static unsigned char ipmi_version_minor;
297 298
299/* If a pretimeout occurs, this is used to allow only one panic to happen. */
300static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
298 301
299static int ipmi_heartbeat(void); 302static int ipmi_heartbeat(void);
300static void panic_halt_ipmi_heartbeat(void); 303static void panic_halt_ipmi_heartbeat(void);
@@ -837,9 +840,10 @@ static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg,
837static void ipmi_wdog_pretimeout_handler(void *handler_data) 840static void ipmi_wdog_pretimeout_handler(void *handler_data)
838{ 841{
839 if (preaction_val != WDOG_PRETIMEOUT_NONE) { 842 if (preaction_val != WDOG_PRETIMEOUT_NONE) {
840 if (preop_val == WDOG_PREOP_PANIC) 843 if (preop_val == WDOG_PREOP_PANIC) {
841 panic("Watchdog pre-timeout"); 844 if (atomic_inc_and_test(&preop_panic_excl))
842 else if (preop_val == WDOG_PREOP_GIVE_DATA) { 845 panic("Watchdog pre-timeout");
846 } else if (preop_val == WDOG_PREOP_GIVE_DATA) {
843 spin_lock(&ipmi_read_lock); 847 spin_lock(&ipmi_read_lock);
844 data_to_read = 1; 848 data_to_read = 1;
845 wake_up_interruptible(&read_q); 849 wake_up_interruptible(&read_q);
@@ -913,7 +917,8 @@ ipmi_nmi(void *dev_id, struct pt_regs *regs, int cpu, int handled)
913 an error and not work unless we re-enable 917 an error and not work unless we re-enable
914 the timer. So do so. */ 918 the timer. So do so. */
915 pretimeout_since_last_heartbeat = 1; 919 pretimeout_since_last_heartbeat = 1;
916 panic(PFX "pre-timeout"); 920 if (atomic_inc_and_test(&preop_panic_excl))
921 panic(PFX "pre-timeout");
917 } 922 }
918 923
919 return NOTIFY_DONE; 924 return NOTIFY_DONE;