diff options
author | Frederic Weisbecker <frederic@kernel.org> | 2017-10-26 22:42:36 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-10-27 03:55:30 -0400 |
commit | 6f1982fedd59856bcc42a9b521be4c3ffd2f60a7 (patch) | |
tree | 47b01dba865b5ed2d4b889787a0660c2911ccd5b | |
parent | de201559df872f83d0c08fb4effe3efd28e6cbc8 (diff) |
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>
-rw-r--r-- | include/linux/sched/isolation.h | 1 | ||||
-rw-r--r-- | include/linux/tick.h | 2 | ||||
-rw-r--r-- | init/Kconfig | 1 | ||||
-rw-r--r-- | kernel/sched/isolation.c | 42 | ||||
-rw-r--r-- | kernel/time/tick-sched.c | 13 |
5 files changed, 36 insertions, 23 deletions
diff --git a/include/linux/sched/isolation.h b/include/linux/sched/isolation.h index 9bb753eece3b..e53cfa96e91e 100644 --- a/include/linux/sched/isolation.h +++ b/include/linux/sched/isolation.h | |||
@@ -10,6 +10,7 @@ enum hk_flags { | |||
10 | HK_FLAG_RCU = (1 << 1), | 10 | HK_FLAG_RCU = (1 << 1), |
11 | HK_FLAG_MISC = (1 << 2), | 11 | HK_FLAG_MISC = (1 << 2), |
12 | HK_FLAG_SCHED = (1 << 3), | 12 | HK_FLAG_SCHED = (1 << 3), |
13 | HK_FLAG_TICK = (1 << 4), | ||
13 | }; | 14 | }; |
14 | 15 | ||
15 | #ifdef CONFIG_CPU_ISOLATION | 16 | #ifdef CONFIG_CPU_ISOLATION |
diff --git a/include/linux/tick.h b/include/linux/tick.h index 68afc09aa8ac..e2a163a9f96c 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, | |||
228 | 228 | ||
229 | extern void tick_nohz_full_kick_cpu(int cpu); | 229 | extern void tick_nohz_full_kick_cpu(int cpu); |
230 | extern void __tick_nohz_task_switch(void); | 230 | extern void __tick_nohz_task_switch(void); |
231 | extern void __init tick_nohz_full_setup(cpumask_var_t cpumask); | ||
231 | #else | 232 | #else |
232 | static inline bool tick_nohz_full_enabled(void) { return false; } | 233 | static inline bool tick_nohz_full_enabled(void) { return false; } |
233 | static inline bool tick_nohz_full_cpu(int cpu) { return false; } | 234 | 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, | |||
248 | 249 | ||
249 | static inline void tick_nohz_full_kick_cpu(int cpu) { } | 250 | static inline void tick_nohz_full_kick_cpu(int cpu) { } |
250 | static inline void __tick_nohz_task_switch(void) { } | 251 | static inline void __tick_nohz_task_switch(void) { } |
252 | static inline void tick_nohz_full_setup(cpumask_var_t cpumask) { } | ||
251 | #endif | 253 | #endif |
252 | 254 | ||
253 | static inline void tick_nohz_task_switch(void) | 255 | static inline void tick_nohz_task_switch(void) |
diff --git a/init/Kconfig b/init/Kconfig index 6f52e6f4bd9d..f8564df58d0a 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -474,7 +474,6 @@ endmenu # "CPU/Task time and stats accounting" | |||
474 | 474 | ||
475 | config CPU_ISOLATION | 475 | config CPU_ISOLATION |
476 | bool "CPU isolation" | 476 | bool "CPU isolation" |
477 | depends on NO_HZ_FULL | ||
478 | help | 477 | help |
479 | Make sure that CPUs running critical tasks are not disturbed by | 478 | Make sure that CPUs running critical tasks are not disturbed by |
480 | any source of "noise" such as unbound workqueues, timers, kthreads... | 479 | any source of "noise" such as unbound workqueues, timers, kthreads... |
diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c index 37a138a780ff..1f61e440358d 100644 --- a/kernel/sched/isolation.c +++ b/kernel/sched/isolation.c | |||
@@ -54,23 +54,41 @@ EXPORT_SYMBOL_GPL(housekeeping_test_cpu); | |||
54 | 54 | ||
55 | void __init housekeeping_init(void) | 55 | void __init housekeeping_init(void) |
56 | { | 56 | { |
57 | if (!tick_nohz_full_enabled()) | 57 | if (!housekeeping_flags) |
58 | return; | 58 | return; |
59 | 59 | ||
60 | if (!alloc_cpumask_var(&housekeeping_mask, GFP_KERNEL)) { | 60 | static_branch_enable(&housekeeping_overriden); |
61 | WARN(1, "NO_HZ: Can't allocate not-full dynticks cpumask\n"); | 61 | |
62 | cpumask_clear(tick_nohz_full_mask); | 62 | /* We need at least one CPU to handle housekeeping work */ |
63 | tick_nohz_full_running = false; | 63 | WARN_ON_ONCE(cpumask_empty(housekeeping_mask)); |
64 | return; | 64 | } |
65 | |||
66 | #ifdef CONFIG_NO_HZ_FULL | ||
67 | static int __init housekeeping_nohz_full_setup(char *str) | ||
68 | { | ||
69 | cpumask_var_t non_housekeeping_mask; | ||
70 | |||
71 | alloc_bootmem_cpumask_var(&non_housekeeping_mask); | ||
72 | if (cpulist_parse(str, non_housekeeping_mask) < 0) { | ||
73 | pr_warn("Housekeeping: Incorrect nohz_full cpumask\n"); | ||
74 | free_bootmem_cpumask_var(non_housekeeping_mask); | ||
75 | return 0; | ||
65 | } | 76 | } |
66 | 77 | ||
67 | cpumask_andnot(housekeeping_mask, | 78 | alloc_bootmem_cpumask_var(&housekeeping_mask); |
68 | cpu_possible_mask, tick_nohz_full_mask); | 79 | cpumask_andnot(housekeeping_mask, cpu_possible_mask, non_housekeeping_mask); |
69 | 80 | ||
70 | housekeeping_flags = HK_FLAG_TIMER | HK_FLAG_RCU | HK_FLAG_MISC; | 81 | if (cpumask_empty(housekeeping_mask)) |
82 | cpumask_set_cpu(smp_processor_id(), housekeeping_mask); | ||
71 | 83 | ||
72 | static_branch_enable(&housekeeping_overriden); | 84 | housekeeping_flags = HK_FLAG_TICK | HK_FLAG_TIMER | |
85 | HK_FLAG_RCU | HK_FLAG_MISC; | ||
73 | 86 | ||
74 | /* We need at least one CPU to handle housekeeping work */ | 87 | tick_nohz_full_setup(non_housekeeping_mask); |
75 | WARN_ON_ONCE(cpumask_empty(housekeeping_mask)); | 88 | |
89 | free_bootmem_cpumask_var(non_housekeeping_mask); | ||
90 | |||
91 | return 1; | ||
76 | } | 92 | } |
93 | __setup("nohz_full=", housekeeping_nohz_full_setup); | ||
94 | #endif | ||
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 27d7d522ac4e..69f3dbe38984 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c | |||
@@ -385,20 +385,13 @@ out: | |||
385 | local_irq_restore(flags); | 385 | local_irq_restore(flags); |
386 | } | 386 | } |
387 | 387 | ||
388 | /* Parse the boot-time nohz CPU list from the kernel parameters. */ | 388 | /* Get the boot-time nohz CPU list from the kernel parameters. */ |
389 | static int __init tick_nohz_full_setup(char *str) | 389 | void __init tick_nohz_full_setup(cpumask_var_t cpumask) |
390 | { | 390 | { |
391 | alloc_bootmem_cpumask_var(&tick_nohz_full_mask); | 391 | alloc_bootmem_cpumask_var(&tick_nohz_full_mask); |
392 | if (cpulist_parse(str, tick_nohz_full_mask) < 0) { | 392 | cpumask_copy(tick_nohz_full_mask, cpumask); |
393 | pr_warn("NO_HZ: Incorrect nohz_full cpumask\n"); | ||
394 | free_bootmem_cpumask_var(tick_nohz_full_mask); | ||
395 | return 1; | ||
396 | } | ||
397 | tick_nohz_full_running = true; | 393 | tick_nohz_full_running = true; |
398 | |||
399 | return 1; | ||
400 | } | 394 | } |
401 | __setup("nohz_full=", tick_nohz_full_setup); | ||
402 | 395 | ||
403 | static int tick_nohz_cpu_down(unsigned int cpu) | 396 | static int tick_nohz_cpu_down(unsigned int cpu) |
404 | { | 397 | { |