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


Reply via email to