The existing housekeeping infrastructure uses a single static cpumask for all isolation types. This prevents independent runtime reconfiguration of different services (like RCU vs. timers).
Introduce dynamic allocation for housekeeping masks to support DHEI. This allows subsequent patches to manage service-specific masks independently at runtime. Signed-off-by: Qiliang Yuan <[email protected]> --- kernel/sched/isolation.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c index 3ad0d6df6a0a2..67a5ff273ea08 100644 --- a/kernel/sched/isolation.c +++ b/kernel/sched/isolation.c @@ -8,6 +8,7 @@ * */ #include <linux/sched/isolation.h> +#include <linux/mutex.h> #include "sched.h" enum hk_flags { @@ -16,6 +17,7 @@ enum hk_flags { HK_FLAG_KERNEL_NOISE = BIT(HK_TYPE_KERNEL_NOISE), }; +static DEFINE_MUTEX(housekeeping_mutex); DEFINE_STATIC_KEY_FALSE(housekeeping_overridden); EXPORT_SYMBOL_GPL(housekeeping_overridden); @@ -105,8 +107,14 @@ void __init housekeeping_init(void) static void __init housekeeping_setup_type(enum hk_type type, cpumask_var_t housekeeping_staging) { + unsigned int gfp = GFP_KERNEL; + + if (!slab_is_available()) + gfp = GFP_NOWAIT; + + if (!housekeeping.cpumasks[type]) + alloc_cpumask_var(&housekeeping.cpumasks[type], gfp); - alloc_bootmem_cpumask_var(&housekeeping.cpumasks[type]); cpumask_copy(housekeeping.cpumasks[type], housekeeping_staging); } @@ -116,6 +124,10 @@ static int __init housekeeping_setup(char *str, unsigned long flags) cpumask_var_t non_housekeeping_mask, housekeeping_staging; unsigned int first_cpu; int err = 0; + unsigned int gfp = GFP_KERNEL; + + if (!slab_is_available()) + gfp = GFP_NOWAIT; if ((flags & HK_FLAG_KERNEL_NOISE) && !(housekeeping.flags & HK_FLAG_KERNEL_NOISE)) { if (!IS_ENABLED(CONFIG_NO_HZ_FULL)) { @@ -125,13 +137,17 @@ static int __init housekeeping_setup(char *str, unsigned long flags) } } - alloc_bootmem_cpumask_var(&non_housekeeping_mask); + if (!alloc_cpumask_var(&non_housekeeping_mask, gfp)) + return 0; + if (cpulist_parse(str, non_housekeeping_mask) < 0) { pr_warn("Housekeeping: nohz_full= or isolcpus= incorrect CPU range\n"); goto free_non_housekeeping_mask; } - alloc_bootmem_cpumask_var(&housekeeping_staging); + if (!alloc_cpumask_var(&housekeeping_staging, gfp)) + goto free_non_housekeeping_mask; + cpumask_andnot(housekeeping_staging, cpu_possible_mask, non_housekeeping_mask); @@ -203,9 +219,9 @@ static int __init housekeeping_setup(char *str, unsigned long flags) err = 1; free_housekeeping_staging: - free_bootmem_cpumask_var(housekeeping_staging); + free_cpumask_var(housekeeping_staging); free_non_housekeeping_mask: - free_bootmem_cpumask_var(non_housekeeping_mask); + free_cpumask_var(non_housekeeping_mask); return err; } -- 2.43.0

