]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
cpuset: Propagate cpuset isolation update to workqueue through housekeeping
authorFrederic Weisbecker <frederic@kernel.org>
Wed, 28 May 2025 16:19:23 +0000 (18:19 +0200)
committerFrederic Weisbecker <frederic@kernel.org>
Tue, 3 Feb 2026 14:23:34 +0000 (15:23 +0100)
Until now, cpuset would propagate isolated partition changes to
workqueues so that unbound workers get properly reaffined.

Since housekeeping now centralizes, synchronize and propagates isolation
cpumask changes, perform the work from that subsystem for consolidation
and consistency purposes.

For simplification purpose, the target function is adapted to take the
new housekeeping mask instead of the isolated mask.

Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
Reviewed-by: Waiman Long <longman@redhat.com>
Acked-by: Tejun Heo <tj@kernel.org>
Cc: "Michal Koutný" <mkoutny@suse.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Cc: Marco Crivellari <marco.crivellari@suse.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tejun Heo <tj@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vlastimil Babka <vbabka@suse.cz>
Cc: Waiman Long <longman@redhat.com>
Cc: cgroups@vger.kernel.org
include/linux/workqueue.h
init/Kconfig
kernel/cgroup/cpuset.c
kernel/sched/isolation.c
kernel/workqueue.c

index dabc351cc127d4d4a074b01581618a565a3c4864..a4749f56398fd6cd721bcf6573918199c52f2cca 100644 (file)
@@ -588,7 +588,7 @@ struct workqueue_attrs *alloc_workqueue_attrs_noprof(void);
 void free_workqueue_attrs(struct workqueue_attrs *attrs);
 int apply_workqueue_attrs(struct workqueue_struct *wq,
                          const struct workqueue_attrs *attrs);
-extern int workqueue_unbound_exclude_cpumask(cpumask_var_t cpumask);
+extern int workqueue_unbound_housekeeping_update(const struct cpumask *hk);
 
 extern bool queue_work_on(int cpu, struct workqueue_struct *wq,
                        struct work_struct *work);
index fa79feb8fe57bb01d8ce8f35e33535709b57d452..518830fb812f3742d003f7deb862d580d2b9ef91 100644 (file)
@@ -1254,6 +1254,7 @@ config CPUSETS
        bool "Cpuset controller"
        depends on SMP
        select UNION_FIND
+       select CPU_ISOLATION
        help
          This option will let you create and manage CPUSETs which
          allow dynamically partitioning a system into sets of CPUs and
index e146e1f34bf97a061206481fb1bea9d486e08706..6309ec5d7b2a1edfc8a39bd64a30771e819c7d8c 100644 (file)
@@ -1482,15 +1482,12 @@ static void update_isolation_cpumasks(void)
        if (!isolated_cpus_updating)
                return;
 
-       ret = workqueue_unbound_exclude_cpumask(isolated_cpus);
+       ret = housekeeping_update(isolated_cpus);
        WARN_ON_ONCE(ret < 0);
 
        ret = tmigr_isolated_exclude_cpumask(isolated_cpus);
        WARN_ON_ONCE(ret < 0);
 
-       ret = housekeeping_update(isolated_cpus);
-       WARN_ON_ONCE(ret < 0);
-
        isolated_cpus_updating = false;
 }
 
index 1e4c3154b0a4c6b716d4a77c820014d44df82653..5bcb6d760f20bdd6b5b1e09a92b3944c239c64af 100644 (file)
@@ -121,6 +121,7 @@ EXPORT_SYMBOL_GPL(housekeeping_test_cpu);
 int housekeeping_update(struct cpumask *isol_mask)
 {
        struct cpumask *trial, *old = NULL;
+       int err;
 
        lockdep_assert_cpus_held();
 
@@ -148,6 +149,8 @@ int housekeeping_update(struct cpumask *isol_mask)
        pci_probe_flush_workqueue();
        mem_cgroup_flush_workqueue();
        vmstat_flush_workqueue();
+       err = workqueue_unbound_housekeeping_update(housekeeping_cpumask(HK_TYPE_DOMAIN));
+       WARN_ON_ONCE(err < 0);
 
        kfree(old);
 
index 253311af47c6d3f09810103b96d0e238a2cacec9..eb566001322207aa9bfdc8130f41d5f29f632510 100644 (file)
@@ -6959,13 +6959,16 @@ static int workqueue_apply_unbound_cpumask(const cpumask_var_t unbound_cpumask)
 }
 
 /**
- * workqueue_unbound_exclude_cpumask - Exclude given CPUs from unbound cpumask
- * @exclude_cpumask: the cpumask to be excluded from wq_unbound_cpumask
+ * workqueue_unbound_housekeeping_update - Propagate housekeeping cpumask update
+ * @hk: the new housekeeping cpumask
  *
- * This function can be called from cpuset code to provide a set of isolated
- * CPUs that should be excluded from wq_unbound_cpumask.
+ * Update the unbound workqueue cpumask on top of the new housekeeping cpumask such
+ * that the effective unbound affinity is the intersection of the new housekeeping
+ * with the requested affinity set via nohz_full=/isolcpus= or sysfs.
+ *
+ * Return: 0 on success and -errno on failure.
  */
-int workqueue_unbound_exclude_cpumask(cpumask_var_t exclude_cpumask)
+int workqueue_unbound_housekeeping_update(const struct cpumask *hk)
 {
        cpumask_var_t cpumask;
        int ret = 0;
@@ -6981,14 +6984,14 @@ int workqueue_unbound_exclude_cpumask(cpumask_var_t exclude_cpumask)
         * (HK_TYPE_WQ ∩ HK_TYPE_DOMAIN) house keeping mask and rewritten
         * by any subsequent write to workqueue/cpumask sysfs file.
         */
-       if (!cpumask_andnot(cpumask, wq_requested_unbound_cpumask, exclude_cpumask))
+       if (!cpumask_and(cpumask, wq_requested_unbound_cpumask, hk))
                cpumask_copy(cpumask, wq_requested_unbound_cpumask);
        if (!cpumask_equal(cpumask, wq_unbound_cpumask))
                ret = workqueue_apply_unbound_cpumask(cpumask);
 
        /* Save the current isolated cpumask & export it via sysfs */
        if (!ret)
-               cpumask_copy(wq_isolated_cpumask, exclude_cpumask);
+               cpumask_andnot(wq_isolated_cpumask, cpu_possible_mask, hk);
 
        mutex_unlock(&wq_pool_mutex);
        free_cpumask_var(cpumask);