aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/ipmi/ipmi_watchdog.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-28 20:19:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-28 20:19:28 -0400
commit532bfc851a7475fb6a36c1e953aa395798a7cca7 (patch)
treea7892e5a31330dd59f31959efbe9fda1803784fd /drivers/char/ipmi/ipmi_watchdog.c
parent0195c00244dc2e9f522475868fa278c473ba7339 (diff)
parent8da00edc1069f01c34510fa405dc15d96c090a3f (diff)
Merge branch 'akpm' (Andrew's patch-bomb)
Merge third batch of patches from Andrew Morton: - Some MM stragglers - core SMP library cleanups (on_each_cpu_mask) - Some IPI optimisations - kexec - kdump - IPMI - the radix-tree iterator work - various other misc bits. "That'll do for -rc1. I still have ~10 patches for 3.4, will send those along when they've baked a little more." * emailed from Andrew Morton <akpm@linux-foundation.org>: (35 commits) backlight: fix typo in tosa_lcd.c crc32: add help text for the algorithm select option mm: move hugepage test examples to tools/testing/selftests/vm mm: move slabinfo.c to tools/vm mm: move page-types.c from Documentation to tools/vm selftests/Makefile: make `run_tests' depend on `all' selftests: launch individual selftests from the main Makefile radix-tree: use iterators in find_get_pages* functions radix-tree: rewrite gang lookup using iterator radix-tree: introduce bit-optimized iterator fs/proc/namespaces.c: prevent crash when ns_entries[] is empty nbd: rename the nbd_device variable from lo to nbd pidns: add reboot_pid_ns() to handle the reboot syscall sysctl: use bitmap library functions ipmi: use locks on watchdog timeout set on reboot ipmi: simplify locking ipmi: fix message handling during panics ipmi: use a tasklet for handling received messages ipmi: increase KCS timeouts ipmi: decrease the IPMI message transaction time in interrupt mode ...
Diffstat (limited to 'drivers/char/ipmi/ipmi_watchdog.c')
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 020a6aec2d86..7ed356e52035 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -520,6 +520,7 @@ static void panic_halt_ipmi_heartbeat(void)
520 msg.cmd = IPMI_WDOG_RESET_TIMER; 520 msg.cmd = IPMI_WDOG_RESET_TIMER;
521 msg.data = NULL; 521 msg.data = NULL;
522 msg.data_len = 0; 522 msg.data_len = 0;
523 atomic_add(2, &panic_done_count);
523 rv = ipmi_request_supply_msgs(watchdog_user, 524 rv = ipmi_request_supply_msgs(watchdog_user,
524 (struct ipmi_addr *) &addr, 525 (struct ipmi_addr *) &addr,
525 0, 526 0,
@@ -528,8 +529,8 @@ static void panic_halt_ipmi_heartbeat(void)
528 &panic_halt_heartbeat_smi_msg, 529 &panic_halt_heartbeat_smi_msg,
529 &panic_halt_heartbeat_recv_msg, 530 &panic_halt_heartbeat_recv_msg,
530 1); 531 1);
531 if (!rv) 532 if (rv)
532 atomic_add(2, &panic_done_count); 533 atomic_sub(2, &panic_done_count);
533} 534}
534 535
535static struct ipmi_smi_msg panic_halt_smi_msg = { 536static struct ipmi_smi_msg panic_halt_smi_msg = {
@@ -553,16 +554,18 @@ static void panic_halt_ipmi_set_timeout(void)
553 /* Wait for the messages to be free. */ 554 /* Wait for the messages to be free. */
554 while (atomic_read(&panic_done_count) != 0) 555 while (atomic_read(&panic_done_count) != 0)
555 ipmi_poll_interface(watchdog_user); 556 ipmi_poll_interface(watchdog_user);
557 atomic_add(2, &panic_done_count);
556 rv = i_ipmi_set_timeout(&panic_halt_smi_msg, 558 rv = i_ipmi_set_timeout(&panic_halt_smi_msg,
557 &panic_halt_recv_msg, 559 &panic_halt_recv_msg,
558 &send_heartbeat_now); 560 &send_heartbeat_now);
559 if (!rv) { 561 if (rv) {
560 atomic_add(2, &panic_done_count); 562 atomic_sub(2, &panic_done_count);
561 if (send_heartbeat_now)
562 panic_halt_ipmi_heartbeat();
563 } else
564 printk(KERN_WARNING PFX 563 printk(KERN_WARNING PFX
565 "Unable to extend the watchdog timeout."); 564 "Unable to extend the watchdog timeout.");
565 } else {
566 if (send_heartbeat_now)
567 panic_halt_ipmi_heartbeat();
568 }
566 while (atomic_read(&panic_done_count) != 0) 569 while (atomic_read(&panic_done_count) != 0)
567 ipmi_poll_interface(watchdog_user); 570 ipmi_poll_interface(watchdog_user);
568} 571}
@@ -1164,7 +1167,7 @@ static int wdog_reboot_handler(struct notifier_block *this,
1164 if (code == SYS_POWER_OFF || code == SYS_HALT) { 1167 if (code == SYS_POWER_OFF || code == SYS_HALT) {
1165 /* Disable the WDT if we are shutting down. */ 1168 /* Disable the WDT if we are shutting down. */
1166 ipmi_watchdog_state = WDOG_TIMEOUT_NONE; 1169 ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
1167 panic_halt_ipmi_set_timeout(); 1170 ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
1168 } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { 1171 } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) {
1169 /* Set a long timer to let the reboot happens, but 1172 /* Set a long timer to let the reboot happens, but
1170 reboot if it hangs, but only if the watchdog 1173 reboot if it hangs, but only if the watchdog
@@ -1172,7 +1175,7 @@ static int wdog_reboot_handler(struct notifier_block *this,
1172 timeout = 120; 1175 timeout = 120;
1173 pretimeout = 0; 1176 pretimeout = 0;
1174 ipmi_watchdog_state = WDOG_TIMEOUT_RESET; 1177 ipmi_watchdog_state = WDOG_TIMEOUT_RESET;
1175 panic_halt_ipmi_set_timeout(); 1178 ipmi_set_timeout(IPMI_SET_TIMEOUT_NO_HB);
1176 } 1179 }
1177 } 1180 }
1178 return NOTIFY_OK; 1181 return NOTIFY_OK;