Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da0d12ff authored by Vladimir Zapolskiy's avatar Vladimir Zapolskiy Committed by Wim Van Sebroeck
Browse files

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: default avatarVladimir Zapolskiy <vladimir_zapolskiy@mentor.com>
Reviewed-by: default avatarGuenter Roeck <linux@roeck-us.net>
Reviewed-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Tested-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarWim Van Sebroeck <wim@iguana.be>
parent f77710c4
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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
+47 −0
Original line number Diff line number Diff line
/*
 * 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");
+2 −4
Original line number Diff line number Diff line
@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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