Initialize watchdog_cpumask from HK_TYPE_KERNEL_NOISE rather than HK_TYPE_TIMER at boot, so the initial mask already reflects any CPUs excluded by nohz_full= on the kernel command line.
Register a housekeeping_cbs so watchdog_cpumask stays in sync with HK_TYPE_KERNEL_NOISE when isolation boundaries change at runtime via cpuset isolated partitions. The apply() callback copies the new housekeeping mask into watchdog_cpumask and triggers __lockup_detector_reconfigure() to restart watchdog threads on the updated CPU set. When nohz_full= is absent at boot, tick_nohz_full_running remains false and DHM isolated partitions do not activate tick suppression. In that case watchdog_hk_apply() is a no-op: there is no need to reconfigure the watchdog CPU set because the full nohz_full infrastructure was never initialized. Signed-off-by: Jing Wu <[email protected]> Signed-off-by: Qiliang Yuan <[email protected]> --- kernel/watchdog.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 87dd5e0f6968d..998ad94da4cb9 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -1389,7 +1389,7 @@ void __init lockup_detector_init(void) pr_info("Disabling watchdog on nohz_full cores by default\n"); cpumask_copy(&watchdog_cpumask, - housekeeping_cpumask(HK_TYPE_TIMER)); + housekeeping_cpumask(HK_TYPE_KERNEL_NOISE)); if (!watchdog_hardlockup_probe()) watchdog_hardlockup_available = true; @@ -1398,3 +1398,57 @@ void __init lockup_detector_init(void) lockup_detector_setup(); } + +/* + * Watchdog housekeeping callback: resync watchdog_cpumask with + * HK_TYPE_KERNEL_NOISE when isolation boundaries change at runtime. + */ +#ifdef CONFIG_CPU_ISOLATION +static void watchdog_hk_apply(enum hk_type type) +{ + const struct cpumask *hk; + + /* + * When nohz_full= was not given at boot, tick_nohz_full_running + * remains false and the full nohz_full infrastructure was never + * initialised. DHM isolated partitions do not activate tick + * suppression in that case, so there is no need to reconfigure the + * watchdog CPU set. + */ +#ifdef CONFIG_NO_HZ_FULL + if (!READ_ONCE(tick_nohz_full_running)) + return; +#endif + + hk = housekeeping_cpumask(HK_TYPE_KERNEL_NOISE); + if (mutex_trylock(&watchdog_mutex)) { + cpumask_copy(&watchdog_cpumask, hk); + __lockup_detector_reconfigure(false); + mutex_unlock(&watchdog_mutex); + } +} + +static int watchdog_hk_validate(enum hk_type type, + const struct cpumask *cur_mask, + const struct cpumask *new_mask) +{ + return 0; +} + +static struct housekeeping_cbs watchdog_hk_cbs = { + .name = "watchdog", + .pre_validate = watchdog_hk_validate, + .apply = watchdog_hk_apply, +}; + +static int __init watchdog_hk_init(void) +{ + int ret; + + ret = housekeeping_register_cbs(HK_TYPE_KERNEL_NOISE, &watchdog_hk_cbs); + if (ret) + pr_debug("watchdog: hk callback registration skipped (%d)\n", ret); + return 0; +} +late_initcall(watchdog_hk_init); +#endif -- 2.43.0

