diff options
-rw-r--r-- | drivers/char/ipmi/ipmi_watchdog.c | 13 |
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; | |||
295 | static unsigned char ipmi_version_major; | 296 | static unsigned char ipmi_version_major; |
296 | static unsigned char ipmi_version_minor; | 297 | static unsigned char ipmi_version_minor; |
297 | 298 | ||
299 | /* If a pretimeout occurs, this is used to allow only one panic to happen. */ | ||
300 | static atomic_t preop_panic_excl = ATOMIC_INIT(-1); | ||
298 | 301 | ||
299 | static int ipmi_heartbeat(void); | 302 | static int ipmi_heartbeat(void); |
300 | static void panic_halt_ipmi_heartbeat(void); | 303 | static void panic_halt_ipmi_heartbeat(void); |
@@ -837,9 +840,10 @@ static void ipmi_wdog_msg_handler(struct ipmi_recv_msg *msg, | |||
837 | static void ipmi_wdog_pretimeout_handler(void *handler_data) | 840 | static 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; |