[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>
This commit is contained in:
Родитель
789cd4702b
Коммит
44df75353b
|
@ -19,30 +19,41 @@ Last reviewed: 06/02/2009
|
||||||
not be updated in a timely fashion and a hardware system reset (also known as
|
not be updated in a timely fashion and a hardware system reset (also known as
|
||||||
an Automatic Server Recovery (ASR)) event will occur.
|
an Automatic Server Recovery (ASR)) event will occur.
|
||||||
|
|
||||||
The hpwdt driver also has three (3) module parameters. They are the following:
|
The hpwdt driver also has four (4) module parameters. They are the following:
|
||||||
|
|
||||||
soft_margin - allows the user to set the watchdog timer value
|
soft_margin - allows the user to set the watchdog timer value
|
||||||
allow_kdump - allows the user to save off a kernel dump image after an NMI
|
allow_kdump - allows the user to save off a kernel dump image after an NMI
|
||||||
nowayout - basic watchdog parameter that does not allow the timer to
|
nowayout - basic watchdog parameter that does not allow the timer to
|
||||||
be restarted or an impending ASR to be escaped.
|
be restarted or an impending ASR to be escaped.
|
||||||
|
priority - determines whether or not the hpwdt driver is first on the
|
||||||
|
die_notify list to handle NMIs or last. The default value
|
||||||
|
for this module parameter is 0 or LAST. If the user wants to
|
||||||
|
enable NMI sourcing then reload the hpwdt driver with
|
||||||
|
priority=1 (and boot with nmi_watchdog=0).
|
||||||
|
|
||||||
NOTE: More information about watchdog drivers in general, including the ioctl
|
NOTE: More information about watchdog drivers in general, including the ioctl
|
||||||
interface to /dev/watchdog can be found in
|
interface to /dev/watchdog can be found in
|
||||||
Documentation/watchdog/watchdog-api.txt and Documentation/IPMI.txt.
|
Documentation/watchdog/watchdog-api.txt and Documentation/IPMI.txt.
|
||||||
|
|
||||||
The NMI sourcing capability is disabled when the driver discovers that the
|
The priority parameter was introduced due to other kernel software that relied
|
||||||
nmi_watchdog is turned on (nmi_watchdog = 1). This is due to the inability to
|
on handling NMIs (like oprofile). Keeping hpwdt's priority at 0 (or LAST)
|
||||||
|
enables the users of NMIs for non critical events to be work as expected.
|
||||||
|
|
||||||
|
The NMI sourcing capability is disabled by default due to the inability to
|
||||||
distinguish between "NMI Watchdog Ticks" and "HW generated NMI events" in the
|
distinguish between "NMI Watchdog Ticks" and "HW generated NMI events" in the
|
||||||
Linux kernel. What this means is that the hpwdt nmi handler code is called
|
Linux kernel. What this means is that the hpwdt nmi handler code is called
|
||||||
each time the NMI signal fires off. This could amount to several thousands of
|
each time the NMI signal fires off. This could amount to several thousands of
|
||||||
NMIs in a matter of seconds. If a user sees the Linux kernel's "dazed and
|
NMIs in a matter of seconds. If a user sees the Linux kernel's "dazed and
|
||||||
confused" message in the logs or if the system gets into a hung state, then
|
confused" message in the logs or if the system gets into a hung state, then
|
||||||
the user should reboot with nmi_watchdog=0.
|
the hpwdt driver can be reloaded with the "priority" module parameter set
|
||||||
|
(priority=1).
|
||||||
|
|
||||||
1. If the kernel has not been booted with nmi_watchdog turned off then
|
1. If the kernel has not been booted with nmi_watchdog turned off then
|
||||||
edit /boot/grub/menu.lst and place the nmi_watchdog=0 at the end of the
|
edit /boot/grub/menu.lst and place the nmi_watchdog=0 at the end of the
|
||||||
currently booting kernel line.
|
currently booting kernel line.
|
||||||
2. reboot the sever
|
2. reboot the sever
|
||||||
|
3. Once the system comes up perform a rmmod hpwdt
|
||||||
|
4. insmod /lib/modules/`uname -r`/kernel/drivers/char/watchdog/hpwdt.ko priority=1
|
||||||
|
|
||||||
Now, the hpwdt can successfully receive and source the NMI and provide a log
|
Now, the hpwdt can successfully receive and source the NMI and provide a log
|
||||||
message that details the reason for the NMI (as determined by the HP BIOS).
|
message that details the reason for the NMI (as determined by the HP BIOS).
|
||||||
|
|
|
@ -120,7 +120,8 @@ static int nowayout = WATCHDOG_NOWAYOUT;
|
||||||
static char expect_release;
|
static char expect_release;
|
||||||
static unsigned long hpwdt_is_open;
|
static unsigned long hpwdt_is_open;
|
||||||
static unsigned int allow_kdump;
|
static unsigned int allow_kdump;
|
||||||
static int hpwdt_nmi_sourcing;
|
static unsigned int hpwdt_nmi_sourcing;
|
||||||
|
static unsigned int priority; /* hpwdt at end of die_notify list */
|
||||||
|
|
||||||
static void __iomem *pci_mem_addr; /* the PCI-memory address */
|
static void __iomem *pci_mem_addr; /* the PCI-memory address */
|
||||||
static unsigned long __iomem *hpwdt_timer_reg;
|
static unsigned long __iomem *hpwdt_timer_reg;
|
||||||
|
@ -623,7 +624,7 @@ static struct miscdevice hpwdt_miscdev = {
|
||||||
|
|
||||||
static struct notifier_block die_notifier = {
|
static struct notifier_block die_notifier = {
|
||||||
.notifier_call = hpwdt_pretimeout,
|
.notifier_call = hpwdt_pretimeout,
|
||||||
.priority = 0x7FFFFFFF,
|
.priority = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -641,7 +642,8 @@ static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
|
||||||
hpwdt_nmi_sourcing = 1;
|
hpwdt_nmi_sourcing = 1;
|
||||||
else
|
else
|
||||||
dev_warn(&dev->dev, "NMI sourcing is disabled. To enable this "
|
dev_warn(&dev->dev, "NMI sourcing is disabled. To enable this "
|
||||||
"functionality you must reboot with nmi_watchdog=0.\n");
|
"functionality you must reboot with nmi_watchdog=0 "
|
||||||
|
"and load the hpwdt driver with priority=1.\n");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
|
static void __devinit hpwdt_check_nmi_sourcing(struct pci_dev *dev)
|
||||||
|
@ -714,6 +716,14 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
|
||||||
cmn_regs.u1.rah = 0x0D;
|
cmn_regs.u1.rah = 0x0D;
|
||||||
cmn_regs.u1.ral = 0x02;
|
cmn_regs.u1.ral = 0x02;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the priority is set to 1, then we will be put first on the
|
||||||
|
* die notify list to handle a critical NMI. The default is to
|
||||||
|
* be last so other users of the NMI signal can function.
|
||||||
|
*/
|
||||||
|
if (priority)
|
||||||
|
die_notifier.priority = 0x7FFFFFFF;
|
||||||
|
|
||||||
retval = register_die_notifier(&die_notifier);
|
retval = register_die_notifier(&die_notifier);
|
||||||
if (retval != 0) {
|
if (retval != 0) {
|
||||||
dev_warn(&dev->dev,
|
dev_warn(&dev->dev,
|
||||||
|
@ -733,9 +743,11 @@ static int __devinit hpwdt_init_one(struct pci_dev *dev,
|
||||||
printk(KERN_INFO
|
printk(KERN_INFO
|
||||||
"hp Watchdog Timer Driver: %s"
|
"hp Watchdog Timer Driver: %s"
|
||||||
", timer margin: %d seconds (nowayout=%d)"
|
", timer margin: %d seconds (nowayout=%d)"
|
||||||
", allow kernel dump: %s (default = 0/OFF).\n",
|
", allow kernel dump: %s (default = 0/OFF)"
|
||||||
|
", priority: %s (default = 0/LAST).\n",
|
||||||
HPWDT_VERSION, soft_margin, nowayout,
|
HPWDT_VERSION, soft_margin, nowayout,
|
||||||
(allow_kdump == 0) ? "OFF" : "ON");
|
(allow_kdump == 0) ? "OFF" : "ON",
|
||||||
|
(priority == 0) ? "LAST" : "FIRST");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -798,5 +810,9 @@ module_param(nowayout, int, 0);
|
||||||
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
|
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
|
||||||
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
|
||||||
|
|
||||||
|
module_param(priority, int, 0);
|
||||||
|
MODULE_PARM_DESC(priority, "The hpwdt driver handles NMIs first or last"
|
||||||
|
" (default = 0/Last)\n");
|
||||||
|
|
||||||
module_init(hpwdt_init);
|
module_init(hpwdt_init);
|
||||||
module_exit(hpwdt_cleanup);
|
module_exit(hpwdt_cleanup);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче