#include <linux/poll.h>
#include <linux/string.h>
#include <linux/ctype.h>
+#include <asm/atomic.h>
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/apic.h>
#endif
static unsigned char ipmi_version_major;
static unsigned char ipmi_version_minor;
+/* If a pretimeout occurs, this is used to allow only one panic to happen. */
+static atomic_t preop_panic_excl = ATOMIC_INIT(-1);
static int ipmi_heartbeat(void);
static void panic_halt_ipmi_heartbeat(void);
static void ipmi_wdog_pretimeout_handler(void *handler_data)
{
if (preaction_val != WDOG_PRETIMEOUT_NONE) {
- if (preop_val == WDOG_PREOP_PANIC)
- panic("Watchdog pre-timeout");
- else if (preop_val == WDOG_PREOP_GIVE_DATA) {
+ if (preop_val == WDOG_PREOP_PANIC) {
+ if (atomic_inc_and_test(&preop_panic_excl))
+ panic("Watchdog pre-timeout");
+ } else if (preop_val == WDOG_PREOP_GIVE_DATA) {
spin_lock(&ipmi_read_lock);
data_to_read = 1;
wake_up_interruptible(&read_q);
an error and not work unless we re-enable
the timer. So do so. */
pretimeout_since_last_heartbeat = 1;
- panic(PFX "pre-timeout");
+ if (atomic_inc_and_test(&preop_panic_excl))
+ panic(PFX "pre-timeout");
}
return NOTIFY_DONE;