Support dynamic reconfiguration of CPU isolation by making the managed interrupts responsive to housekeeping mask changes at runtime.
1. Register a housekeeping notifier in the genirq subsystem to listen for HK_TYPE_MANAGED_IRQ updates. 2. Iterate through all active interrupts when a mask update occurs. 3. Re-apply affinity for managed interrupts to ensure they honor the newly configured housekeeping mask. 4. Use irq_set_affinity_locked() to trigger migration away from newly isolated CPUs or towards newly designated housekeeping CPUs. Signed-off-by: Qiliang Yuan <[email protected]> Signed-off-by: Qiliang Yuan <[email protected]> --- kernel/irq/manage.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 349ae7979da0..9523f0655b12 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -21,6 +21,7 @@ #include <linux/sched/isolation.h> #include <uapi/linux/sched/types.h> #include <linux/task_work.h> +#include <linux/cpuhotplug.h> #include "internals.h" @@ -2811,3 +2812,54 @@ bool irq_check_status_bit(unsigned int irq, unsigned int bitmask) return res; } EXPORT_SYMBOL_GPL(irq_check_status_bit); + +#ifdef CONFIG_SMP +static int irq_housekeeping_reconfigure(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct housekeeping_update *upd = data; + struct irq_desc *desc; + unsigned int irq; + + if (action != HK_UPDATE_MASK || upd->type != HK_TYPE_MANAGED_IRQ) + return NOTIFY_OK; + + irq_lock_sparse(); + for_each_active_irq(irq) { + struct irq_data *id; + + desc = irq_to_desc(irq); + if (!desc) + continue; + + scoped_guard(raw_spinlock_irqsave, &desc->lock) { + id = irq_desc_get_irq_data(desc); + if (!irqd_affinity_is_managed(id) || !desc->action || + !irq_data_get_irq_chip(id)) + continue; + + /* + * Re-apply existing affinity to honor the new + * housekeeping mask via __irq_set_affinity() logic. + */ + irq_set_affinity_locked(id, irq_data_get_affinity_mask(id), false); + } + } + irq_unlock_sparse(); + + return NOTIFY_OK; +} + +static struct notifier_block irq_housekeeping_nb = { + .notifier_call = irq_housekeeping_reconfigure, +}; + +static int __init irq_init_housekeeping_notifier(void) +{ + housekeeping_register_notifier(&irq_housekeeping_nb); + return 0; +} +core_initcall(irq_init_housekeeping_notifier); +#endif + + -- 2.51.0

