]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
watchdog: pretimeout: add panic pretimeout governor
authorVladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Fri, 7 Oct 2016 12:39:56 +0000 (15:39 +0300)
committerWim Van Sebroeck <wim@iguana.be>
Sat, 8 Oct 2016 08:27:17 +0000 (10:27 +0200)
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>
drivers/watchdog/Kconfig
drivers/watchdog/Makefile
drivers/watchdog/pretimeout_panic.c [new file with mode: 0644]
drivers/watchdog/watchdog_pretimeout.c
drivers/watchdog/watchdog_pretimeout.h

index 4aeb8f95beb4c8d0ebb48a9c338bb4f54dd608e1..cbd33321c0f8d4c84a3f52838502d9708fe8e89f 100644 (file)
@@ -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
index 0502a21db1dbe7e0a3934d96820333418bf4d318..1a34c6a9698807ab3455d59f08a72d329d92ef6e 100644 (file)
@@ -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 (file)
index 0000000..0c197a1
--- /dev/null
@@ -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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/watchdog.h>
+
+#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 <vladimir_zapolskiy@mentor.com>");
+MODULE_DESCRIPTION("Panic watchdog pretimeout governor");
+MODULE_LICENSE("GPL");
index 72612255fb552b70c9398d7fb7cb26dfbc3f73d8..098c965f6c7866a5ccdf787fa5251913d01c90d4 100644 (file)
@@ -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;
index c4b6f88dc9c95cfdd170ef0d9fb3f0de46884cd3..867492aa7ea64759a8da921930ea061239208de6 100644 (file)
@@ -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