Re: [PATCH 3/3] watchdog: add lockup_sys_info sysctl to dump sys info on system lockup
From: Feng Tang
Date: Tue Nov 11 2025 - 09:09:13 EST
On Tue, Nov 11, 2025 at 02:26:05PM +0100, Petr Mladek wrote:
> On Thu 2025-11-06 10:30:32, Feng Tang wrote:
> > When soft/hard lockup happens, developers may need different kinds of
> > system information (call-stacks, memory info, locks, etc.) to help debugging.
> >
> > Add 'lockup_sys_info' sysctl knob to take human readable string like
> > "tasks,mem,timers,locks,ftrace,...", and when system lockup happens, all
> > requested information will be dumped. (refer kernel/sys_info.c for more
> > details).
> >
> > --- a/kernel/watchdog.c
> > +++ b/kernel/watchdog.c
> > @@ -53,6 +54,13 @@ static int __read_mostly watchdog_hardlockup_available;
> > struct cpumask watchdog_cpumask __read_mostly;
> > unsigned long *watchdog_cpumask_bits = cpumask_bits(&watchdog_cpumask);
> >
> > +/*
> > + * A bitmask to control what kinds of system info to be printed when
> > + * system lockup is detected, it could be task, memory, lock etc. Refer
> > + * include/linux/sys_info.h for detailed bit definition.
> > + */
> > +static unsigned long lockup_si_mask;
> > +
> > #ifdef CONFIG_HARDLOCKUP_DETECTOR
> >
> > # ifdef CONFIG_SMP
> > @@ -240,6 +248,7 @@ void watchdog_hardlockup_check(unsigned int cpu, struct pt_regs *regs)
> > clear_bit_unlock(0, &hard_lockup_nmi_warn);
> > }
>
> The code right above printed backtaces from all CPUs when
> sysctl_hardlockup_all_cpu_backtrace.
>
> > + sys_info(lockup_si_mask);
>
> And sys_info() could print it again when SYS_INFO_ALL_BT
> bit is set. The hard lockup detector should use the same
> trick as the softlockup detector in watchdog_timer_fn().
Yes, I missed that. Thanks for the catching!
> > if (hardlockup_panic)
> > nmi_panic(regs, "Hard LOCKUP");
> >
> > @@ -746,9 +755,11 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
> > unsigned long touch_ts, period_ts, now;
> > struct pt_regs *regs = get_irq_regs();
> > int duration;
> > - int softlockup_all_cpu_backtrace = sysctl_softlockup_all_cpu_backtrace;
> > + int softlockup_all_cpu_backtrace;
> > unsigned long flags;
> >
> > + softlockup_all_cpu_backtrace = (lockup_si_mask & SYS_INFO_ALL_BT) ?
> > + 1 : sysctl_softlockup_all_cpu_backtrace;
> > if (!watchdog_enabled)
> > return HRTIMER_NORESTART;
> >
> > @@ -846,6 +857,7 @@ static enum hrtimer_restart watchdog_timer_fn(struct hrtimer *hrtimer)
> > }
> >
> > add_taint(TAINT_SOFTLOCKUP, LOCKDEP_STILL_OK);
> > + sys_info(lockup_si_mask & ~SYS_INFO_ALL_BT);
> > if (softlockup_panic)
> > panic("softlockup: hung tasks");
> > }
> > @@ -1178,6 +1190,13 @@ static const struct ctl_table watchdog_sysctls[] = {
> > .mode = 0644,
> > .proc_handler = proc_watchdog_cpumask,
> > },
> > + {
> > + .procname = "lockup_sys_info",
> > + .data = &lockup_si_mask,
> > + .maxlen = sizeof(lockup_si_mask),
> > + .mode = 0644,
> > + .proc_handler = sysctl_sys_info_handler,
> > + },
>
> There already exists:
>
> + hardlockup_all_cpu_backtrace
> + hardlockup_panic
> + softlockup_all_cpu_backtrace
> + softlockup_panic
>
> IMHO, it would make sense to introduce separate:
>
> + hardlockup_sys_info
> + softlockup_sys_info
Make sense to me, will do.
Thanks,
Feng