sched/isolation: Handle the nohz_full= parameter

We want to centralize the isolation management, done by 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= will be deprecated in the future. We want to control
the isolation features from the isolcpus= parameter.

Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Chris Metcalf <cmetcalf@mellanox.com>
Cc: Christoph Lameter <cl@linux.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Luiz Capitulino <lcapitulino@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Rik van Riel <riel@redhat.com>
Cc: Wanpeng Li <kernellwp@gmail.com>
Link: http://lkml.kernel.org/r/1509072159-31808-10-git-send-email-frederic@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Frederic Weisbecker 2017-10-27 04:42:36 +02:00 committed by Ingo Molnar
parent de201559df
commit 6f1982fedd
5 changed files with 37 additions and 24 deletions

View File

@ -10,6 +10,7 @@ enum hk_flags {
HK_FLAG_RCU = (1 << 1), HK_FLAG_RCU = (1 << 1),
HK_FLAG_MISC = (1 << 2), HK_FLAG_MISC = (1 << 2),
HK_FLAG_SCHED = (1 << 3), HK_FLAG_SCHED = (1 << 3),
HK_FLAG_TICK = (1 << 4),
}; };
#ifdef CONFIG_CPU_ISOLATION #ifdef CONFIG_CPU_ISOLATION

View File

@ -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_full_kick_cpu(int cpu);
extern void __tick_nohz_task_switch(void); extern void __tick_nohz_task_switch(void);
extern void __init tick_nohz_full_setup(cpumask_var_t cpumask);
#else #else
static inline bool tick_nohz_full_enabled(void) { return false; } static inline bool tick_nohz_full_enabled(void) { return false; }
static inline bool tick_nohz_full_cpu(int cpu) { return false; } static inline bool tick_nohz_full_cpu(int cpu) { return false; }
@ -248,6 +249,7 @@ static inline void tick_dep_clear_signal(struct signal_struct *signal,
static inline void tick_nohz_full_kick_cpu(int cpu) { } static inline void tick_nohz_full_kick_cpu(int cpu) { }
static inline void __tick_nohz_task_switch(void) { } static inline void __tick_nohz_task_switch(void) { }
static inline void tick_nohz_full_setup(cpumask_var_t cpumask) { }
#endif #endif
static inline void tick_nohz_task_switch(void) static inline void tick_nohz_task_switch(void)

View File

@ -474,7 +474,6 @@ endmenu # "CPU/Task time and stats accounting"
config CPU_ISOLATION config CPU_ISOLATION
bool "CPU isolation" bool "CPU isolation"
depends on NO_HZ_FULL
help help
Make sure that CPUs running critical tasks are not disturbed by Make sure that CPUs running critical tasks are not disturbed by
any source of "noise" such as unbound workqueues, timers, kthreads... any source of "noise" such as unbound workqueues, timers, kthreads...

View File

@ -54,23 +54,41 @@ EXPORT_SYMBOL_GPL(housekeeping_test_cpu);
void __init housekeeping_init(void) void __init housekeeping_init(void)
{ {
if (!tick_nohz_full_enabled()) if (!housekeeping_flags)
return; 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); static_branch_enable(&housekeeping_overriden);
/* We need at least one CPU to handle housekeeping work */ /* We need at least one CPU to handle housekeeping work */
WARN_ON_ONCE(cpumask_empty(housekeeping_mask)); WARN_ON_ONCE(cpumask_empty(housekeeping_mask));
} }
#ifdef CONFIG_NO_HZ_FULL
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);
#endif

View File

@ -385,20 +385,13 @@ void __tick_nohz_task_switch(void)
local_irq_restore(flags); local_irq_restore(flags);
} }
/* Parse the boot-time nohz CPU list from the kernel parameters. */ /* Get the boot-time nohz CPU list from the kernel parameters. */
static int __init tick_nohz_full_setup(char *str) void __init tick_nohz_full_setup(cpumask_var_t cpumask)
{ {
alloc_bootmem_cpumask_var(&tick_nohz_full_mask); alloc_bootmem_cpumask_var(&tick_nohz_full_mask);
if (cpulist_parse(str, tick_nohz_full_mask) < 0) { cpumask_copy(tick_nohz_full_mask, cpumask);
pr_warn("NO_HZ: Incorrect nohz_full cpumask\n");
free_bootmem_cpumask_var(tick_nohz_full_mask);
return 1;
}
tick_nohz_full_running = true; tick_nohz_full_running = true;
return 1;
} }
__setup("nohz_full=", tick_nohz_full_setup);
static int tick_nohz_cpu_down(unsigned int cpu) static int tick_nohz_cpu_down(unsigned int cpu)
{ {