aboutsummaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorStephane Eranian <eranian@google.com>2013-04-03 08:21:33 -0400
committerIngo Molnar <mingo@kernel.org>2013-05-28 03:07:10 -0400
commit9e6302056f8029f438e853432a856b9f13de26a6 (patch)
tree2c777b710fb4624fda55be17306d6f107b72428c /init
parentab573844e3058eef2788803d373019f8bebead57 (diff)
perf: Use hrtimers for event multiplexing
The current scheme of using the timer tick was fine for per-thread events. However, it was causing bias issues in system-wide mode (including for uncore PMUs). Event groups would not get their fair share of runtime on the PMU. With tickless kernels, if a core is idle there is no timer tick, and thus no event rotation (multiplexing). However, there are events (especially uncore events) which do count even though cores are asleep. This patch changes the timer source for multiplexing. It introduces a per-PMU per-cpu hrtimer. The advantage is that even when a core goes idle, it will come back to service the hrtimer, thus multiplexing on system-wide events works much better. The per-PMU implementation (suggested by PeterZ) enables adjusting the multiplexing interval per PMU. The preferred interval is stashed into the struct pmu. If not set, it will be forced to the default interval value. In order to minimize the impact of the hrtimer, it is turned on and off on demand. When the PMU on a CPU is overcommited, the hrtimer is activated. It is stopped when the PMU is not overcommitted. In order for this to work properly, we had to change the order of initialization in start_kernel() such that hrtimer_init() is run before perf_event_init(). The default interval in milliseconds is set to a timer tick just like with the old code. We will provide a sysctl to tune this in another patch. Signed-off-by: Stephane Eranian <eranian@google.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Link: http://lkml.kernel.org/r/1364991694-5876-2-git-send-email-eranian@google.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'init')
-rw-r--r--init/main.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/init/main.c b/init/main.c
index 9484f4ba88d0..ec549581d732 100644
--- a/init/main.c
+++ b/init/main.c
@@ -542,7 +542,6 @@ asmlinkage void __init start_kernel(void)
542 if (WARN(!irqs_disabled(), "Interrupts were enabled *very* early, fixing it\n")) 542 if (WARN(!irqs_disabled(), "Interrupts were enabled *very* early, fixing it\n"))
543 local_irq_disable(); 543 local_irq_disable();
544 idr_init_cache(); 544 idr_init_cache();
545 perf_event_init();
546 rcu_init(); 545 rcu_init();
547 tick_nohz_init(); 546 tick_nohz_init();
548 radix_tree_init(); 547 radix_tree_init();
@@ -555,6 +554,7 @@ asmlinkage void __init start_kernel(void)
555 softirq_init(); 554 softirq_init();
556 timekeeping_init(); 555 timekeeping_init();
557 time_init(); 556 time_init();
557 perf_event_init();
558 profile_init(); 558 profile_init();
559 call_function_init(); 559 call_function_init();
560 WARN(!irqs_disabled(), "Interrupts were enabled early\n"); 560 WARN(!irqs_disabled(), "Interrupts were enabled early\n");