diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 4aeb8f95beb4..cbd33321c0f8 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1856,6 +1856,14 @@ config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP governor is selected by a user, write a short message to the kernel log buffer and don't do any system changes. +config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC + bool "panic" + select WATCHDOG_PRETIMEOUT_GOV_PANIC + help + Use panic watchdog pretimeout governor by default, if + a watchdog pretimeout event happens, consider that + a watchdog feeder is dead and reboot is unavoidable. + endchoice config WATCHDOG_PRETIMEOUT_GOV_NOOP @@ -1864,6 +1872,12 @@ config WATCHDOG_PRETIMEOUT_GOV_NOOP Noop watchdog pretimeout governor, only an informational message is added to kernel log buffer. +config WATCHDOG_PRETIMEOUT_GOV_PANIC + tristate "Panic watchdog pretimeout governor" + help + Panic watchdog pretimeout governor, on watchdog pretimeout + event put the kernel into panic. + endif # WATCHDOG_PRETIMEOUT_GOV endif # WATCHDOG diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 0502a21db1db..1a34c6a96988 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -10,6 +10,7 @@ watchdog-objs += watchdog_core.o watchdog_dev.o watchdog-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV) += watchdog_pretimeout.o obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP) += pretimeout_noop.o +obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC) += pretimeout_panic.o # Only one watchdog can succeed. We probe the ISA/PCI/USB based # watchdog-cards first, then the architecture specific watchdog diff --git a/drivers/watchdog/pretimeout_panic.c b/drivers/watchdog/pretimeout_panic.c new file mode 100644 index 000000000000..0c197a1c97f4 --- /dev/null +++ b/drivers/watchdog/pretimeout_panic.c @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2015-2016 Mentor Graphics + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include + +#include "watchdog_pretimeout.h" + +/** + * pretimeout_panic - Panic on watchdog pretimeout event + * @wdd - watchdog_device + * + * Panic, watchdog has not been fed till pretimeout event. + */ +static void pretimeout_panic(struct watchdog_device *wdd) +{ + panic("watchdog pretimeout event\n"); +} + +static struct watchdog_governor watchdog_gov_panic = { + .name = "panic", + .pretimeout = pretimeout_panic, +}; + +static int __init watchdog_gov_panic_register(void) +{ + return watchdog_register_governor(&watchdog_gov_panic); +} + +static void __exit watchdog_gov_panic_unregister(void) +{ + watchdog_unregister_governor(&watchdog_gov_panic); +} +module_init(watchdog_gov_panic_register); +module_exit(watchdog_gov_panic_unregister); + +MODULE_AUTHOR("Vladimir Zapolskiy "); +MODULE_DESCRIPTION("Panic watchdog pretimeout governor"); +MODULE_LICENSE("GPL"); diff --git a/drivers/watchdog/watchdog_pretimeout.c b/drivers/watchdog/watchdog_pretimeout.c index 72612255fb55..098c965f6c78 100644 --- a/drivers/watchdog/watchdog_pretimeout.c +++ b/drivers/watchdog/watchdog_pretimeout.c @@ -60,7 +60,8 @@ int watchdog_register_governor(struct watchdog_governor *gov) { struct watchdog_pretimeout *p; - if (!default_gov) { + if (!strncmp(gov->name, WATCHDOG_PRETIMEOUT_DEFAULT_GOV, + WATCHDOG_GOV_NAME_MAXLEN)) { spin_lock_irq(&pretimeout_lock); default_gov = gov; @@ -79,9 +80,6 @@ void watchdog_unregister_governor(struct watchdog_governor *gov) struct watchdog_pretimeout *p; spin_lock_irq(&pretimeout_lock); - if (gov == default_gov) - default_gov = NULL; - list_for_each_entry(p, &pretimeout_list, entry) if (p->wdd->gov == gov) p->wdd->gov = default_gov; diff --git a/drivers/watchdog/watchdog_pretimeout.h b/drivers/watchdog/watchdog_pretimeout.h index c4b6f88dc9c9..867492aa7ea6 100644 --- a/drivers/watchdog/watchdog_pretimeout.h +++ b/drivers/watchdog/watchdog_pretimeout.h @@ -22,6 +22,8 @@ int watchdog_pretimeout_governor_get(struct watchdog_device *wdd, char *buf); #if IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP) #define WATCHDOG_PRETIMEOUT_DEFAULT_GOV "noop" +#elif IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC) +#define WATCHDOG_PRETIMEOUT_DEFAULT_GOV "panic" #endif #else