Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

watchdog: pretimeout: add panic pretimeout governor

The change adds panic watchdog pretimeout governor, on watchdog
pretimeout event the kernel shall panic. In general watchdog
pretimeout event means that something essentially bad is going on the
system, for example a process scheduler stalls or watchdog feeder is
killed due to OOM, so printing out information attendant to panic and
before likely unavoidable reboot caused by a watchdog may help to
determine a root cause of the issue.

Signed-off-by: Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>

authored by

Vladimir Zapolskiy and committed by
Wim Van Sebroeck
da0d12ff f77710c4

+66 -4
+14
drivers/watchdog/Kconfig
··· 1856 1856 governor is selected by a user, write a short message to 1857 1857 the kernel log buffer and don't do any system changes. 1858 1858 1859 + config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC 1860 + bool "panic" 1861 + select WATCHDOG_PRETIMEOUT_GOV_PANIC 1862 + help 1863 + Use panic watchdog pretimeout governor by default, if 1864 + a watchdog pretimeout event happens, consider that 1865 + a watchdog feeder is dead and reboot is unavoidable. 1866 + 1859 1867 endchoice 1860 1868 1861 1869 config WATCHDOG_PRETIMEOUT_GOV_NOOP ··· 1871 1863 help 1872 1864 Noop watchdog pretimeout governor, only an informational 1873 1865 message is added to kernel log buffer. 1866 + 1867 + config WATCHDOG_PRETIMEOUT_GOV_PANIC 1868 + tristate "Panic watchdog pretimeout governor" 1869 + help 1870 + Panic watchdog pretimeout governor, on watchdog pretimeout 1871 + event put the kernel into panic. 1874 1872 1875 1873 endif # WATCHDOG_PRETIMEOUT_GOV 1876 1874
+1
drivers/watchdog/Makefile
··· 10 10 watchdog-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV) += watchdog_pretimeout.o 11 11 12 12 obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP) += pretimeout_noop.o 13 + obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC) += pretimeout_panic.o 13 14 14 15 # Only one watchdog can succeed. We probe the ISA/PCI/USB based 15 16 # watchdog-cards first, then the architecture specific watchdog
+47
drivers/watchdog/pretimeout_panic.c
··· 1 + /* 2 + * Copyright (C) 2015-2016 Mentor Graphics 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License as published by 6 + * the Free Software Foundation; either version 2 of the License, or 7 + * (at your option) any later version. 8 + * 9 + */ 10 + 11 + #include <linux/kernel.h> 12 + #include <linux/module.h> 13 + #include <linux/watchdog.h> 14 + 15 + #include "watchdog_pretimeout.h" 16 + 17 + /** 18 + * pretimeout_panic - Panic on watchdog pretimeout event 19 + * @wdd - watchdog_device 20 + * 21 + * Panic, watchdog has not been fed till pretimeout event. 22 + */ 23 + static void pretimeout_panic(struct watchdog_device *wdd) 24 + { 25 + panic("watchdog pretimeout event\n"); 26 + } 27 + 28 + static struct watchdog_governor watchdog_gov_panic = { 29 + .name = "panic", 30 + .pretimeout = pretimeout_panic, 31 + }; 32 + 33 + static int __init watchdog_gov_panic_register(void) 34 + { 35 + return watchdog_register_governor(&watchdog_gov_panic); 36 + } 37 + 38 + static void __exit watchdog_gov_panic_unregister(void) 39 + { 40 + watchdog_unregister_governor(&watchdog_gov_panic); 41 + } 42 + module_init(watchdog_gov_panic_register); 43 + module_exit(watchdog_gov_panic_unregister); 44 + 45 + MODULE_AUTHOR("Vladimir Zapolskiy <vladimir_zapolskiy@mentor.com>"); 46 + MODULE_DESCRIPTION("Panic watchdog pretimeout governor"); 47 + MODULE_LICENSE("GPL");
+2 -4
drivers/watchdog/watchdog_pretimeout.c
··· 60 60 { 61 61 struct watchdog_pretimeout *p; 62 62 63 - if (!default_gov) { 63 + if (!strncmp(gov->name, WATCHDOG_PRETIMEOUT_DEFAULT_GOV, 64 + WATCHDOG_GOV_NAME_MAXLEN)) { 64 65 spin_lock_irq(&pretimeout_lock); 65 66 default_gov = gov; 66 67 ··· 80 79 struct watchdog_pretimeout *p; 81 80 82 81 spin_lock_irq(&pretimeout_lock); 83 - if (gov == default_gov) 84 - default_gov = NULL; 85 - 86 82 list_for_each_entry(p, &pretimeout_list, entry) 87 83 if (p->wdd->gov == gov) 88 84 p->wdd->gov = default_gov;
+2
drivers/watchdog/watchdog_pretimeout.h
··· 22 22 23 23 #if IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP) 24 24 #define WATCHDOG_PRETIMEOUT_DEFAULT_GOV "noop" 25 + #elif IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_PANIC) 26 + #define WATCHDOG_PRETIMEOUT_DEFAULT_GOV "panic" 25 27 #endif 26 28 27 29 #else