watchdog: pretimeout: Add "dump" pretimeout governor

Add a new "dump" pretimeout governor that triggers a backtrace of all
CPUs (via trigger_all_cpu_backtrace()) to the kernel log buffer.  This
provides diagnostic information right before the hardware watchdog
fires.

In addition, update the WATCHDOG_PRETIMEOUT_GOV_SEL Kconfig logic to
fall back to the "panic" governor only when both "noop" and "dump"
governors are disabled.

Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://lore.kernel.org/r/20260707102105.3600275-1-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
This commit is contained in:
Tzung-Bi Shih
2026-08-10 09:00:03 -07:00
committed by Guenter Roeck
parent dac35bdc5c
commit 8bb763d4c3
4 changed files with 67 additions and 2 deletions
+18 -1
View File
@@ -93,10 +93,19 @@ config WATCHDOG_PRETIMEOUT_GOV_SEL
tristate
depends on WATCHDOG_PRETIMEOUT_GOV
default m
select WATCHDOG_PRETIMEOUT_GOV_PANIC if WATCHDOG_PRETIMEOUT_GOV_NOOP=n
select WATCHDOG_PRETIMEOUT_GOV_PANIC if \
WATCHDOG_PRETIMEOUT_GOV_NOOP=n && WATCHDOG_PRETIMEOUT_GOV_DUMP=n
if WATCHDOG_PRETIMEOUT_GOV
config WATCHDOG_PRETIMEOUT_GOV_DUMP
bool "Dump watchdog pretimeout governor"
depends on WATCHDOG_CORE=y
default WATCHDOG_CORE
help
Dump watchdog pretimeout governor, all cpu backtrace is
added to kernel log buffer.
config WATCHDOG_PRETIMEOUT_GOV_NOOP
tristate "Noop watchdog pretimeout governor"
depends on WATCHDOG_CORE
@@ -121,6 +130,14 @@ choice
The governor takes its action, if a watchdog is capable
to report a pretimeout event.
config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_DUMP
bool "dump"
depends on WATCHDOG_PRETIMEOUT_GOV_DUMP
help
Use dump watchdog pretimeout governor by default. If dump
governor is selected by a user, dump all cpu backtrace to
the kernel log buffer and don't do any system changes.
config WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP
bool "noop"
depends on WATCHDOG_PRETIMEOUT_GOV_NOOP
+1
View File
@@ -11,6 +11,7 @@ watchdog-objs += watchdog_core.o watchdog_dev.o
watchdog-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV) += watchdog_pretimeout.o
watchdog-$(CONFIG_WATCHDOG_HRTIMER_PRETIMEOUT) += watchdog_hrtimer_pretimeout.o
obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_DUMP) += pretimeout_dump.o
obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_NOOP) += pretimeout_noop.o
obj-$(CONFIG_WATCHDOG_PRETIMEOUT_GOV_PANIC) += pretimeout_panic.o
+45
View File
@@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright 2026 Google LLC
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/nmi.h>
#include <linux/watchdog.h>
#include "watchdog_pretimeout.h"
/**
* pretimeout_dump - Dump on watchdog pretimeout event
* @wdd: watchdog_device
*
* Dump all cpu backtrace on pretimeout event.
*/
static void pretimeout_dump(struct watchdog_device *wdd)
{
pr_alert("watchdog%d: pretimeout event\n", wdd->id);
if (!trigger_all_cpu_backtrace())
pr_alert("trigger_all_cpu_backtrace() isn't available\n");
}
static struct watchdog_governor watchdog_gov_dump = {
.name = "dump",
.pretimeout = pretimeout_dump,
};
static int __init watchdog_gov_dump_register(void)
{
return watchdog_register_governor(&watchdog_gov_dump);
}
static void __exit watchdog_gov_dump_unregister(void)
{
watchdog_unregister_governor(&watchdog_gov_dump);
}
module_init(watchdog_gov_dump_register);
module_exit(watchdog_gov_dump_unregister);
MODULE_AUTHOR("Tzung-Bi Shih <tzungbi@kernel.org>");
MODULE_DESCRIPTION("Dump watchdog pretimeout governor");
MODULE_LICENSE("GPL");
+3 -1
View File
@@ -24,7 +24,9 @@ int watchdog_pretimeout_governor_get(struct watchdog_device *wdd, char *buf);
int watchdog_pretimeout_governor_set(struct watchdog_device *wdd,
const char *buf);
#if IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_NOOP)
#if IS_ENABLED(CONFIG_WATCHDOG_PRETIMEOUT_DEFAULT_GOV_DUMP)
#define WATCHDOG_PRETIMEOUT_DEFAULT_GOV "dump"
#elif 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"