Re: [PATCH 2/2] watchdog: pscrr: add watchdog pretimeout reason tracking

Guenter Roeck <[email protected]> Mon, 20 Jul 2026 09:39:08 -0700
Newsgroups org.kernel.vger.linux-watchdog,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pm
Message-ID <[email protected]>
On Tue, Jul 14, 2026 at 03:22:35PM +0530, Faruque Ansari wrote:
> A watchdog pretimeout fires before the actual reset, giving the kernel
> a brief window to record what happened.  Without this change that
> window goes unused and the next boot sees PSCR_UNKNOWN, making it
> impossible to tell a watchdog-driven reset from any other cause.
> 
> Call set_psc_reason(PSCR_WATCHDOG_PRETIMEOUT) at the top of
> watchdog_notify_pretimeout() so the reason is recorded as soon as the
> pretimeout is signalled, before any governor action runs.
> 
> Signed-off-by: Faruque Ansari <[email protected]>
> ---
>  drivers/power/reset/pscrr.c            | 3 ++-
>  drivers/watchdog/watchdog_pretimeout.c | 3 +++
>  include/linux/power/power_on_reason.h  | 1 +
>  include/linux/reboot.h                 | 1 +
>  kernel/reboot.c                        | 1 +

This is a cross-subsystem change. As far as I can see it would
be easy to split it into two patches. Please do that.

Guenter

>  5 files changed, 8 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/power/reset/pscrr.c b/drivers/power/reset/pscrr.c
> index b5906f127e88..36642cf9f27c 100644
> --- a/drivers/power/reset/pscrr.c
> +++ b/drivers/power/reset/pscrr.c
> @@ -149,7 +149,8 @@ static int pscrr_panic_notifier(struct notifier_block *nb,
>  	if (!backend || !backend->ops || !backend->ops->write_reason)
>  		return NOTIFY_OK;
>  
> -	set_psc_reason(PSCR_KERNEL_PANIC);
> +	if (get_psc_reason() != PSCR_WATCHDOG_PRETIMEOUT)
> +		set_psc_reason(PSCR_KERNEL_PANIC);
>  	ret = backend->ops->write_reason(get_psc_reason());
>  	if (ret)
>  		pr_err("PSCRR: Failed to store reason %d (%s) at panic, err=%pe\n",
> diff --git a/drivers/watchdog/watchdog_pretimeout.c b/drivers/watchdog/watchdog_pretimeout.c
> index 02e09b9e396d..ea48d4eca4aa 100644
> --- a/drivers/watchdog/watchdog_pretimeout.c
> +++ b/drivers/watchdog/watchdog_pretimeout.c
> @@ -4,6 +4,7 @@
>   */
>  
>  #include <linux/list.h>
> +#include <linux/reboot.h>
>  #include <linux/slab.h>
>  #include <linux/spinlock.h>
>  #include <linux/string.h>
> @@ -103,6 +104,8 @@ void watchdog_notify_pretimeout(struct watchdog_device *wdd)
>  {
>  	unsigned long flags;
>  
> +	set_psc_reason(PSCR_WATCHDOG_PRETIMEOUT);
> +
>  	spin_lock_irqsave(&pretimeout_lock, flags);
>  	if (!wdd->gov) {
>  		spin_unlock_irqrestore(&pretimeout_lock, flags);
> diff --git a/include/linux/power/power_on_reason.h b/include/linux/power/power_on_reason.h
> index 4ac1bdfdc211..c5846c0ccde4 100644
> --- a/include/linux/power/power_on_reason.h
> +++ b/include/linux/power/power_on_reason.h
> @@ -20,5 +20,6 @@
>  #define POWER_ON_REASON_OVER_TEMPERATURE "over temperature"
>  #define POWER_ON_REASON_EC_PANIC "EC panic"
>  #define POWER_ON_REASON_KERNEL_PANIC "kernel panic"
> +#define POWER_ON_REASON_WATCHDOG_PRETIMEOUT "watchdog pretimeout"
>  
>  #endif /* POWER_ON_REASON_H */
> diff --git a/include/linux/reboot.h b/include/linux/reboot.h
> index a492b1652038..fccbffc9dbef 100644
> --- a/include/linux/reboot.h
> +++ b/include/linux/reboot.h
> @@ -237,6 +237,7 @@ enum psc_reason {
>  	PSCR_OVER_TEMPERATURE,
>  	PSCR_EC_PANIC,
>  	PSCR_KERNEL_PANIC,
> +	PSCR_WATCHDOG_PRETIMEOUT,
>  
>  	/* Number of reasons */
>  	PSCR_REASON_COUNT,
> diff --git a/kernel/reboot.c b/kernel/reboot.c
> index f1df52f8773a..629002a951c2 100644
> --- a/kernel/reboot.c
> +++ b/kernel/reboot.c
> @@ -1066,6 +1066,7 @@ static const char * const pscr_reason_strs[] = {
>  	[PSCR_OVER_TEMPERATURE]   = POWER_ON_REASON_OVER_TEMPERATURE,
>  	[PSCR_EC_PANIC]           = POWER_ON_REASON_EC_PANIC,
>  	[PSCR_KERNEL_PANIC]       = POWER_ON_REASON_KERNEL_PANIC,
> +	[PSCR_WATCHDOG_PRETIMEOUT] = POWER_ON_REASON_WATCHDOG_PRETIMEOUT,
>  };
>  
>  /**