aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/tick-sched.c
diff options
context:
space:
mode:
authorPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-06-04 16:46:03 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2014-07-09 12:15:02 -0400
commitc0f489d2c6fec8994c642c2ec925eb858727dc7b (patch)
treee72f709231a498626a149ef676bd60ff0e1b26c3 /kernel/time/tick-sched.c
parentabaa93d9e1de2c29297e69ddba8ddd38f15064cf (diff)
rcu: Bind grace-period kthreads to non-NO_HZ_FULL CPUs
Binding the grace-period kthreads to the timekeeping CPU resulted in significant performance decreases for some workloads. For more detail, see: https://lkml.org/lkml/2014/6/3/395 for benchmark numbers https://lkml.org/lkml/2014/6/4/218 for CPU statistics It turns out that it is necessary to bind the grace-period kthreads to the timekeeping CPU only when all but CPU 0 is a nohz_full CPU on the one hand or if CONFIG_NO_HZ_FULL_SYSIDLE=y on the other. In other cases, it suffices to bind the grace-period kthreads to the set of non-nohz_full CPUs. This commit therefore creates a tick_nohz_not_full_mask that is the complement of tick_nohz_full_mask, and then binds the grace-period kthread to the set of CPUs indicated by this new mask, which covers the CONFIG_NO_HZ_FULL_SYSIDLE=n case. The CONFIG_NO_HZ_FULL_SYSIDLE=y case still binds the grace-period kthreads to the timekeeping CPU. This commit also includes the tick_nohz_full_enabled() check suggested by Frederic Weisbecker. Reported-by: Jet Chen <jet.chen@intel.com> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> [ paulmck: Created housekeeping_affine() and housekeeping_mask per fweisbec feedback. ]
Diffstat (limited to 'kernel/time/tick-sched.c')
-rw-r--r--kernel/time/tick-sched.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 6558b7ac112d..f784d83e29f1 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -154,6 +154,7 @@ static void tick_sched_handle(struct tick_sched *ts, struct pt_regs *regs)
154 154
155#ifdef CONFIG_NO_HZ_FULL 155#ifdef CONFIG_NO_HZ_FULL
156cpumask_var_t tick_nohz_full_mask; 156cpumask_var_t tick_nohz_full_mask;
157cpumask_var_t housekeeping_mask;
157bool tick_nohz_full_running; 158bool tick_nohz_full_running;
158 159
159static bool can_stop_full_tick(void) 160static bool can_stop_full_tick(void)
@@ -281,6 +282,7 @@ static int __init tick_nohz_full_setup(char *str)
281 int cpu; 282 int cpu;
282 283
283 alloc_bootmem_cpumask_var(&tick_nohz_full_mask); 284 alloc_bootmem_cpumask_var(&tick_nohz_full_mask);
285 alloc_bootmem_cpumask_var(&housekeeping_mask);
284 if (cpulist_parse(str, tick_nohz_full_mask) < 0) { 286 if (cpulist_parse(str, tick_nohz_full_mask) < 0) {
285 pr_warning("NOHZ: Incorrect nohz_full cpumask\n"); 287 pr_warning("NOHZ: Incorrect nohz_full cpumask\n");
286 return 1; 288 return 1;
@@ -291,6 +293,8 @@ static int __init tick_nohz_full_setup(char *str)
291 pr_warning("NO_HZ: Clearing %d from nohz_full range for timekeeping\n", cpu); 293 pr_warning("NO_HZ: Clearing %d from nohz_full range for timekeeping\n", cpu);
292 cpumask_clear_cpu(cpu, tick_nohz_full_mask); 294 cpumask_clear_cpu(cpu, tick_nohz_full_mask);
293 } 295 }
296 cpumask_andnot(housekeeping_mask,
297 cpu_possible_mask, tick_nohz_full_mask);
294 tick_nohz_full_running = true; 298 tick_nohz_full_running = true;
295 299
296 return 1; 300 return 1;
@@ -332,9 +336,15 @@ static int tick_nohz_init_all(void)
332 pr_err("NO_HZ: Can't allocate full dynticks cpumask\n"); 336 pr_err("NO_HZ: Can't allocate full dynticks cpumask\n");
333 return err; 337 return err;
334 } 338 }
339 if (!alloc_cpumask_var(&housekeeping_mask, GFP_KERNEL)) {
340 pr_err("NO_HZ: Can't allocate not-full dynticks cpumask\n");
341 return err;
342 }
335 err = 0; 343 err = 0;
336 cpumask_setall(tick_nohz_full_mask); 344 cpumask_setall(tick_nohz_full_mask);
337 cpumask_clear_cpu(smp_processor_id(), tick_nohz_full_mask); 345 cpumask_clear_cpu(smp_processor_id(), tick_nohz_full_mask);
346 cpumask_clear(housekeeping_mask);
347 cpumask_set_cpu(smp_processor_id(), housekeeping_mask);
338 tick_nohz_full_running = true; 348 tick_nohz_full_running = true;
339#endif 349#endif
340 return err; 350 return err;