Subsystems currently rely on static housekeeping masks determined at boot. Supporting runtime reconfiguration (DHM v2) requires a mechanism to broadcast mask changes to affected kernel components.
Implement a blocking notifier chain for housekeeping mask updates. This infrastructure enables subsystems like genirq, workqueues, and RCU to react dynamically to isolation changes triggered by cpusets. Signed-off-by: Qiliang Yuan <[email protected]> --- include/linux/sched/isolation.h | 21 +++++++++++++++++++++ kernel/sched/isolation.c | 26 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/include/linux/sched/isolation.h b/include/linux/sched/isolation.h index b9a041247565c..aea1dbc4d7486 100644 --- a/include/linux/sched/isolation.h +++ b/include/linux/sched/isolation.h @@ -4,6 +4,7 @@ #include <linux/cpumask.h> #include <linux/init.h> #include <linux/tick.h> +#include <linux/notifier.h> enum hk_type { /* Inverse of boot-time isolcpus= argument */ @@ -28,6 +29,13 @@ enum hk_type { #define HK_TYPE_KERNEL_NOISE HK_TYPE_TICK +struct housekeeping_update { + enum hk_type type; + const struct cpumask *new_mask; +}; + +#define HK_UPDATE_MASK 0x01 + #ifdef CONFIG_CPU_ISOLATION DECLARE_STATIC_KEY_FALSE(housekeeping_overridden); extern int housekeeping_any_cpu(enum hk_type type); @@ -38,6 +46,9 @@ extern bool housekeeping_test_cpu(int cpu, enum hk_type type); extern int housekeeping_update(struct cpumask *isol_mask); extern void __init housekeeping_init(void); +extern int housekeeping_register_notifier(struct notifier_block *nb); +extern int housekeeping_unregister_notifier(struct notifier_block *nb); + #else static inline int housekeeping_any_cpu(enum hk_type type) @@ -65,6 +76,16 @@ static inline bool housekeeping_test_cpu(int cpu, enum hk_type type) static inline int housekeeping_update(struct cpumask *isol_mask) { return 0; } static inline void housekeeping_init(void) { } + +static inline int housekeeping_register_notifier(struct notifier_block *nb) +{ + return 0; +} + +static inline int housekeeping_unregister_notifier(struct notifier_block *nb) +{ + return 0; +} #endif /* CONFIG_CPU_ISOLATION */ static inline bool housekeeping_cpu(int cpu, enum hk_type type) diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c index e05ed5118e651..0462b41807161 100644 --- a/kernel/sched/isolation.c +++ b/kernel/sched/isolation.c @@ -10,6 +10,7 @@ #include <linux/sched/isolation.h> #include <linux/pci.h> #include "sched.h" +#include <linux/notifier.h> enum hk_flags { HK_FLAG_DOMAIN_BOOT = BIT(HK_TYPE_DOMAIN_BOOT), @@ -26,6 +27,8 @@ enum hk_flags { #define HK_FLAG_KERNEL_NOISE (HK_FLAG_TICK | HK_FLAG_TIMER | HK_FLAG_RCU | \ HK_FLAG_MISC | HK_FLAG_WQ | HK_FLAG_KTHREAD) +static BLOCKING_NOTIFIER_HEAD(housekeeping_notifier_list); + DEFINE_STATIC_KEY_FALSE(housekeeping_overridden); EXPORT_SYMBOL_GPL(housekeeping_overridden); @@ -170,6 +173,29 @@ int housekeeping_update(struct cpumask *isol_mask) return 0; } +int housekeeping_register_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&housekeeping_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(housekeeping_register_notifier); + +int housekeeping_unregister_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&housekeeping_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(housekeeping_unregister_notifier); + +int housekeeping_update_notify(enum hk_type type, const struct cpumask *new_mask) +{ + struct housekeeping_update update = { + .type = type, + .new_mask = new_mask, + }; + + return blocking_notifier_call_chain(&housekeeping_notifier_list, HK_UPDATE_MASK, &update); +} +EXPORT_SYMBOL_GPL(housekeeping_update_notify); + void __init housekeeping_init(void) { enum hk_type type; -- 2.43.0

