aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Mingarelli <thomas.mingarelli@hp.com>2009-06-18 19:28:57 -0400
committerWim Van Sebroeck <wim@iguana.be>2009-06-23 03:13:45 -0400
commit44df75353bc8f32e26e049284053a61d4f1047d6 (patch)
tree8ac01af7888c6d5c3746d30834fd63a148305078
parent789cd4702bf830416d2e1794495407be42fe95ad (diff)
[WATCHDOG] hpwdt: Add NMI priority option
Add a priority option so that the user can choose if we do the NMI first or last. Signed-off-by: Thomas Mingarelli <thomas.mingarelli@hp.com> Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
-rw-r--r--Documentation/watchdog/hpwdt.txt19
-rw-r--r--drivers/watchdog/hpwdt.c26
2 files changed, 36 insertions, 9 deletions
diff --git a/Documentation/watchdog/hpwdt.txt b/Documentation/watchdog/hpwdt.txt
index 127839e53043..9c24d5ffbb06 100644
--- a/Documentation/watchdog/hpwdt.txt
+++ b/Documentation/watchdog/hpwdt.txt
@@ -19,30 +19,41 @@ Last reviewed: 06/02/2009
19 not be updated in a timely fashion and a hardware system reset (also known as 19 not be updated in a timely fashion and a hardware system reset (also known as
20 an Automatic Server Recovery (ASR)) event will occur. 20 an Automatic Server Recovery (ASR)) event will occur.
21 21
22 The hpwdt driver also has three (3) module parameters. They are the following: 22 The hpwdt driver also has four (4) module parameters. They are the following:
23 23
24 soft_margin - allows the user to set the watchdog timer value 24 soft_margin - allows the user to set the watchdog timer value
25 allow_kdump - allows the user to save off a kernel dump image after an NMI 25 allow_kdump - allows the user to save off a kernel dump image after an NMI
26 nowayout - basic watchdog parameter that does not allow the timer to 26 nowayout - basic watchdog parameter that does not allow the timer to
27 be restarted or an impending ASR to be escaped. 27 be restarted or an impending ASR to be escaped.
28 priority - determines whether or not the hpwdt driver is first on the
29 die_notify list to handle NMIs or last. The default value
30 for this module parameter is 0 or LAST. If the user wants to
31 enable NMI sourcing then reload the hpwdt driver with
32 priority=1 (and boot with nmi_watchdog=0).
28 33
29 NOTE: More information about watchdog drivers in general, including the ioctl 34 NOTE: More information about watchdog drivers in general, including the ioctl
30 interface to /dev/watchdog can be found in 35 interface to /dev/watchdog can be found in
31 Documentation/watchdog/watchdog-api.txt and Documentation/IPMI.txt. 36 Documentation/watchdog/watchdog-api.txt and Documentation/IPMI.txt.
32 37
33 The NMI sourcing capability is disabled when the driver discovers that the 38 The priority parameter was introduced due to other kernel software that relied
34 nmi_watchdog is turned on (nmi_watchdog = 1). This is due to the inability to 39 on handling NMIs (like oprofile). Keeping hpwdt's priority at 0 (or LAST)
40 enables the users of NMIs for non critical events to be work as expected.
41
42 The NMI sourcing capability is disabled by default due to the inability to
35 distinguish between "NMI Watchdog Ticks" and "HW generated NMI events" in the 43 distinguish between "NMI Watchdog Ticks" and "HW generated NMI events" in the
36 Linux kernel. What this means is that the hpwdt nmi handler code is called 44 Linux kernel. What this means is that the hpwdt nmi handler code is called
37 each time the NMI signal fires off. This could amount to several thousands of 45 each time the NMI signal fires off. This could amount to several thousands of
38 NMIs in a matter of seconds. If a user sees the Linux kernel's "dazed and 46 NMIs in a matter of seconds. If a user sees the Linux kernel's "dazed and
39 confused" message in the logs or if the system gets into a hung state, then 47 confused" message in the logs or if the system gets into a hung state, then
40 the user should reboot with nmi_watchdog=0. 48 the hpwdt driver can be reloaded with the "priority" module parameter set
49 (priority=1).
41 50
42 1. If the kernel has not been booted with nmi_watchdog turned off then 51 1. If the kernel has not been booted with nmi_watchdog turned off then
43 edit /boot/grub/menu.lst and place the nmi_watchdog=0 at the end of the 52 edit /boot/grub/menu.lst and place the nmi_watchdog=0 at the end of the
44 currently booting kernel line. 53 currently booting kernel line.
45 2. reboot the sever 54 2. reboot the sever
55 3. Once the system comes up perform a rmmod hpwdt
56 4. insmod /lib/modules/`uname -r`/kernel/drivers/char/watchdog/hpwdt.ko priority=1
46 57
47 Now, the hpwdt can successfully receive and source the NMI and provide a log 58 Now, the hpwdt can successfully receive and source the NMI and provide a log
48 message that details the reason for the NMI (as determined by the HP BIOS). 59 message that details the reason for the NMI (as determined by the HP BIOS).
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index c0b9169ba5d5..a6c5674c78e6 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -120,7 +120,8 @@ static int nowayout = WATCHDOG_NOWAYOUT;
120static char expect_release; 120static char expect_release;
121static unsigned long hpwdt_is_open; 121static unsigned long hpwdt_is_open;
122static unsigned int allow_kdump; 122static unsigned int allow_kdump;
123static int hpwdt_nmi_sourcing; 123static unsigned int hpwdt_nmi_sourcing;
124static unsigned int priority; /* hpwdt at end of die_notify list */
124 125
125static void __iomem *pci_mem_addr; /* the PCI-memory address */ 126static void __iomem *pci_mem_addr; /* the PCI-memory address */
126static unsigned long __iomem *hpwdt_timer_reg; 127static unsigned long __iomem *hpwdt_timer_reg;
@@ -623,7 +624,7 @@ static struct miscdevice hpwdt_miscdev = {
623 624
624static struct notifier_block die_notifier = { 625static struct notifier_block die_notifier = {
625 .notifier_call = hpwdt_pretimeout, 626 .notifier_call = hpwdt_pretimeout,
626 .priority = 0x7FFFFFFF, 627 .priority = 0,
627}; 628};
628 629
629/* 630/*
@@ -641,7 +642,8 @@ static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
641 hpwdt_nmi_sourcing = 1; 642 hpwdt_nmi_sourcing = 1;
642 else 643 else
643 dev_warn(&dev->dev, "NMI sourcing is disabled. To enable this " 644 dev_warn(&dev->dev, "NMI sourcing is disabled. To enable this "
644 "functionality you must reboot with nmi_watchdog=0.\n"); 645 "functionality you must reboot with nmi_watchdog=0 "
646 "and load the hpwdt driver with priority=1.\n");
645} 647}
646#else 648#else
647static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev) 649static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
@@ -714,6 +716,14 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
714 cmn_regs.u1.rah = 0x0D; 716 cmn_regs.u1.rah = 0x0D;
715 cmn_regs.u1.ral = 0x02; 717 cmn_regs.u1.ral = 0x02;
716 718
719 /*
720 * If the priority is set to 1, then we will be put first on the
721 * die notify list to handle a critical NMI. The default is to
722 * be last so other users of the NMI signal can function.
723 */
724 if (priority)
725 die_notifier.priority = 0x7FFFFFFF;
726
717 retval = register_die_notifier(&die_notifier); 727 retval = register_die_notifier(&die_notifier);
718 if (retval != 0) { 728 if (retval != 0) {
719 dev_warn(&dev->dev, 729 dev_warn(&dev->dev,
@@ -733,9 +743,11 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
733 printk(KERN_INFO 743 printk(KERN_INFO
734 "hp Watchdog Timer Driver: %s" 744 "hp Watchdog Timer Driver: %s"
735 ", timer margin: %d seconds (nowayout=%d)" 745 ", timer margin: %d seconds (nowayout=%d)"
736 ", allow kernel dump: %s (default = 0/OFF).\n", 746 ", allow kernel dump: %s (default = 0/OFF)"
747 ", priority: %s (default = 0/LAST).\n",
737 HPWDT_VERSION, soft_margin, nowayout, 748 HPWDT_VERSION, soft_margin, nowayout,
738 (allow_kdump == 0) ? "OFF" : "ON"); 749 (allow_kdump == 0) ? "OFF" : "ON",
750 (priority == 0) ? "LAST" : "FIRST");
739 751
740 return 0; 752 return 0;
741 753
@@ -798,5 +810,9 @@ module_param(nowayout, int, 0);
798MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 810MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
799 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 811 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
800 812
813module_param(priority, int, 0);
814MODULE_PARM_DESC(priority, "The hpwdt driver handles NMIs first or last"
815 " (default = 0/Last)\n");
816
801module_init(hpwdt_init); 817module_init(hpwdt_init);
802module_exit(hpwdt_cleanup); 818module_exit(hpwdt_cleanup);