We want to centralize the isolation management from the housekeeping subsystem. Therefore we need to handle the nohz_full= parameter from there.
Since nohz_full= so far has involved unbound timers, watchdog, RCU and tilegx NAPI isolation, we keep that default behaviour. nohz_full= is deemed to be deprecated in the future. We want to control the isolation features from the isolcpus= parameter. Signed-off-by: Frederic Weisbecker <fweis...@gmail.com> Cc: Chris Metcalf <cmetc...@mellanox.com> Cc: Rik van Riel <r...@redhat.com> Cc: Peter Zijlstra <pet...@infradead.org> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Mike Galbraith <efa...@gmx.de> Cc: Ingo Molnar <mi...@kernel.org> Cc: Christoph Lameter <c...@linux.com> Cc: Paul E. McKenney <paul...@linux.vnet.ibm.com> Cc: Wanpeng Li <kernel...@gmail.com> Cc: Luiz Capitulino <lcapitul...@redhat.com> --- include/linux/housekeeping.h | 1 + include/linux/tick.h | 1 + kernel/housekeeping.c | 42 +++++++++++++++++++++++++++++------------- kernel/time/tick-sched.c | 13 +++---------- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/include/linux/housekeeping.h b/include/linux/housekeeping.h index 2a9b808..b53a2b2 100644 --- a/include/linux/housekeeping.h +++ b/include/linux/housekeeping.h @@ -12,6 +12,7 @@ enum hk_flags { HK_FLAG_SCHED = (1 << 3), HK_FLAG_WORKQUEUE = (1 << 4), HK_FLAG_KTHREAD = (1 << 5), + HK_FLAG_TICK = (1 << 6), }; #ifdef CONFIG_CPU_ISOLATION diff --git a/include/linux/tick.h b/include/linux/tick.h index 68afc09..3c82cf5 100644 --- a/include/linux/tick.h +++ b/include/linux/tick.h @@ -228,6 +228,7 @@ static inline void tick_dep_clear_signal(struct signal_struct *signal, extern void tick_nohz_full_kick_cpu(int cpu); extern void __tick_nohz_task_switch(void); +extern void __init tick_nohz_full_setup(cpumask_var_t cpumask); #else static inline bool tick_nohz_full_enabled(void) { return false; } static inline bool tick_nohz_full_cpu(int cpu) { return false; } diff --git a/kernel/housekeeping.c b/kernel/housekeeping.c index e2196d1..633a0d9 100644 --- a/kernel/housekeeping.c +++ b/kernel/housekeeping.c @@ -49,23 +49,39 @@ bool housekeeping_test_cpu(int cpu, enum hk_flags flags) void __init housekeeping_init(void) { - if (!tick_nohz_full_enabled()) + if (!housekeeping_flags) return; - if (!alloc_cpumask_var(&housekeeping_mask, GFP_KERNEL)) { - WARN(1, "NO_HZ: Can't allocate not-full dynticks cpumask\n"); - cpumask_clear(tick_nohz_full_mask); - tick_nohz_full_running = false; - return; - } - - cpumask_andnot(housekeeping_mask, - cpu_possible_mask, tick_nohz_full_mask); - - housekeeping_flags = HK_FLAG_TIMER | HK_FLAG_RCU | HK_FLAG_MISC; - static_branch_enable(&housekeeping_overriden); /* We need at least one CPU to handle housekeeping work */ WARN_ON_ONCE(cpumask_empty(housekeeping_mask)); } + +static int __init housekeeping_nohz_full_setup(char *str) +{ + cpumask_var_t non_housekeeping_mask; + + alloc_bootmem_cpumask_var(&non_housekeeping_mask); + if (cpulist_parse(str, non_housekeeping_mask) < 0) { + pr_warn("Housekeeping: Incorrect nohz_full cpumask\n"); + free_bootmem_cpumask_var(non_housekeeping_mask); + return 0; + } + + alloc_bootmem_cpumask_var(&housekeeping_mask); + cpumask_andnot(housekeeping_mask, cpu_possible_mask, non_housekeeping_mask); + + if (cpumask_empty(housekeeping_mask)) + cpumask_set_cpu(smp_processor_id(), housekeeping_mask); + + housekeeping_flags = HK_FLAG_TICK | HK_FLAG_TIMER | + HK_FLAG_RCU | HK_FLAG_MISC; + + tick_nohz_full_setup(non_housekeeping_mask); + + free_bootmem_cpumask_var(non_housekeeping_mask); + + return 1; +} +__setup("nohz_full=", housekeeping_nohz_full_setup); diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 9d29dee..f09dd43 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -384,20 +384,13 @@ void __tick_nohz_task_switch(void) local_irq_restore(flags); } -/* Parse the boot-time nohz CPU list from the kernel parameters. */ -static int __init tick_nohz_full_setup(char *str) +/* Get the boot-time nohz CPU list from the kernel parameters. */ +void __init tick_nohz_full_setup(cpumask_var_t cpumask) { alloc_bootmem_cpumask_var(&tick_nohz_full_mask); - if (cpulist_parse(str, tick_nohz_full_mask) < 0) { - pr_warn("NO_HZ: Incorrect nohz_full cpumask\n"); - free_bootmem_cpumask_var(tick_nohz_full_mask); - return 1; - } + cpumask_copy(tick_nohz_full_mask, cpumask); tick_nohz_full_running = true; - - return 1; } -__setup("nohz_full=", tick_nohz_full_setup); static int tick_nohz_cpu_down(unsigned int cpu) { -- 2.7.4