An isolated cpuset partition already updates the HK_TYPE_DOMAIN housekeeping mask. Extend it to also update the kernel-noise masks (HK_TYPE_KERNEL_NOISE and HK_TYPE_MANAGED_IRQ) so that creating or destroying an isolated partition reconfigures the full set of housekeeping cpumasks.
HK_TYPE_KERNEL_NOISE must stay a subset of HK_TYPE_DOMAIN: a CPU with the tick suppressed still needs to be excluded from the normal sched domain, or scheduler load balancing can keep nominating it as a target. Update the sched domain mask first and only touch the kernel-noise types when that update succeeds, so the two masks can never diverge for the same isolation request. housekeeping_update() and housekeeping_update_types() are called after dropping cpus_read_lock and cpuset_mutex, with only cpuset_top_mutex held for mutual exclusion. Signed-off-by: Qiliang Yuan <[email protected]> --- kernel/cgroup/cpuset.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 3f52717c19654..8b3bb034adf62 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -1431,17 +1431,43 @@ static void cpuset_update_sd_hk_unlock(void) rebuild_sched_domains_locked(); if (update_housekeeping) { + static const unsigned long noise_types = + BIT(HK_TYPE_KERNEL_NOISE) | BIT(HK_TYPE_MANAGED_IRQ); + int ret; + update_housekeeping = false; cpumask_copy(isolated_hk_cpus, isolated_cpus); + mutex_unlock(&cpuset_mutex); + cpus_read_unlock(); + /* * housekeeping_update() is now called without holding * cpus_read_lock and cpuset_mutex. Only cpuset_top_mutex * is still being held for mutual exclusion. */ - mutex_unlock(&cpuset_mutex); - cpus_read_unlock(); - WARN_ON_ONCE(housekeeping_update(isolated_hk_cpus)); + + /* + * Update the sched domain mask first; it must succeed + * before the kernel-noise types because workqueue flush + * and timer migration depend on the sched domain mask. + */ + ret = housekeeping_update(isolated_hk_cpus); + WARN_ON_ONCE(ret); + + /* + * Only touch the kernel-noise housekeeping masks + * (HK_TYPE_KERNEL_NOISE and HK_TYPE_MANAGED_IRQ) once the + * sched domain update above actually succeeded: HK_TYPE_ + * KERNEL_NOISE must stay a subset of HK_TYPE_DOMAIN, so a CPU + * can never end up tick-suppressed while still scheduled as + * part of the normal (non-isolated) sched domain. The tick, + * RCU and managed-interrupt state is reconfigured as the + * affected CPUs are cycled through the CPU hotplug machinery. + */ + if (!ret) + WARN_ON_ONCE(housekeeping_update_types(noise_types, + isolated_hk_cpus)); mutex_unlock(&cpuset_top_mutex); } else { cpuset_full_unlock(); -- 2.43.0

