Skip to content

Commit

Permalink
sched/isolation: Handle the nohz_full= parameter
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Frederic Weisbecker authored and Ingo Molnar committed Oct 27, 2017
1 parent de20155 commit 6f1982f
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 23 deletions.
1 change: 1 addition & 0 deletions include/linux/sched/isolation.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ enum hk_flags {
HK_FLAG_RCU = (1 << 1),
HK_FLAG_MISC = (1 << 2),
HK_FLAG_SCHED = (1 << 3),
HK_FLAG_TICK = (1 << 4),
};

#ifdef CONFIG_CPU_ISOLATION
Expand Down
2 changes: 2 additions & 0 deletions include/linux/tick.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -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_task_switch(void) { }
static inline void tick_nohz_full_setup(cpumask_var_t cpumask) { }
#endif

static inline void tick_nohz_task_switch(void)
Expand Down
1 change: 0 additions & 1 deletion init/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,6 @@ endmenu # "CPU/Task time and stats accounting"

config CPU_ISOLATION
bool "CPU isolation"
depends on NO_HZ_FULL
help
Make sure that CPUs running critical tasks are not disturbed by
any source of "noise" such as unbound workqueues, timers, kthreads...
Expand Down
42 changes: 30 additions & 12 deletions kernel/sched/isolation.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,41 @@ EXPORT_SYMBOL_GPL(housekeeping_test_cpu);

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;
static_branch_enable(&housekeeping_overriden);

/* We need at least one CPU to handle housekeeping work */
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;
}

cpumask_andnot(housekeeping_mask,
cpu_possible_mask, tick_nohz_full_mask);
alloc_bootmem_cpumask_var(&housekeeping_mask);
cpumask_andnot(housekeeping_mask, cpu_possible_mask, non_housekeeping_mask);

housekeeping_flags = HK_FLAG_TIMER | HK_FLAG_RCU | HK_FLAG_MISC;
if (cpumask_empty(housekeeping_mask))
cpumask_set_cpu(smp_processor_id(), housekeeping_mask);

static_branch_enable(&housekeeping_overriden);
housekeeping_flags = HK_FLAG_TICK | HK_FLAG_TIMER |
HK_FLAG_RCU | HK_FLAG_MISC;

/* We need at least one CPU to handle housekeeping work */
WARN_ON_ONCE(cpumask_empty(housekeeping_mask));
tick_nohz_full_setup(non_housekeeping_mask);

free_bootmem_cpumask_var(non_housekeeping_mask);

return 1;
}
__setup("nohz_full=", housekeeping_nohz_full_setup);
#endif
13 changes: 3 additions & 10 deletions kernel/time/tick-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,20 +385,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)
{
Expand Down

0 comments on commit 6f1982f

Please sign in to comment.