Unbound workqueues use HK_TYPE_WQ and HK_TYPE_DOMAIN to determine their default CPU affinity. These boundaries are currently static and only enforced during early boot. Implement a housekeeping notifier to update unbound workqueue affinity. This enables unbound workqueue tasks to respect dynamic isolation boundaries at runtime. Signed-off-by: Qiliang Yuan --- kernel/workqueue.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 253311af47c6d..ef3ef7e3fe81f 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -7904,6 +7904,47 @@ static void __init wq_cpu_intensive_thresh_init(void) wq_cpu_intensive_thresh_us = thresh; } +static int wq_housekeeping_reconfigure(struct notifier_block *nb, + unsigned long action, void *data) +{ + if (action == HK_UPDATE_MASK) { + struct housekeeping_update *upd = data; + unsigned int type = upd->type; + + if (type == HK_TYPE_WQ || type == HK_TYPE_DOMAIN) { + cpumask_var_t cpumask; + + if (!alloc_cpumask_var(&cpumask, GFP_KERNEL)) { + pr_warn("workqueue: failed to allocate cpumask for housekeeping update\n"); + return NOTIFY_BAD; + } + + cpumask_copy(cpumask, cpu_possible_mask); + if (!cpumask_empty(housekeeping_cpumask(HK_TYPE_WQ))) + cpumask_and(cpumask, cpumask, housekeeping_cpumask(HK_TYPE_WQ)); + if (!cpumask_empty(housekeeping_cpumask(HK_TYPE_DOMAIN))) + cpumask_and(cpumask, cpumask, housekeeping_cpumask(HK_TYPE_DOMAIN)); + + workqueue_set_unbound_cpumask(cpumask); + + if (type == HK_TYPE_DOMAIN) { + apply_wqattrs_lock(); + cpumask_andnot(wq_isolated_cpumask, cpu_possible_mask, + housekeeping_cpumask(HK_TYPE_DOMAIN)); + apply_wqattrs_unlock(); + } + + free_cpumask_var(cpumask); + } + } + + return NOTIFY_OK; +} + +static struct notifier_block wq_housekeeping_nb = { + .notifier_call = wq_housekeeping_reconfigure, +}; + /** * workqueue_init - bring workqueue subsystem fully online * @@ -7964,6 +8005,7 @@ void __init workqueue_init(void) wq_online = true; wq_watchdog_init(); + housekeeping_register_notifier(&wq_housekeeping_nb); } /* -- 2.43.0