aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/events/core.c
diff options
context:
space:
mode:
authorEric B Munson <emunson@mgebm.net>2011-06-24 12:26:26 -0400
committerIngo Molnar <mingo@elte.hu>2011-07-01 05:06:34 -0400
commit0d6412085b7ff58612af52e51ffa864f0df4b8fd (patch)
treeb0aa2622aa0262b1238b07fad38d76c9c61d6e32 /kernel/events/core.c
parentc4794295917ebeda8013b6cb9c8d71ab4f74a1fa (diff)
events: Ensure that timers are updated without requiring read() call
The event tracing infrastructure exposes two timers which should be updated each time the value of the counter is updated. Currently, these counters are only updated when userspace calls read() on the fd associated with an event. This means that counters which are read via the mmap'd page exclusively never have their timers updated. This patch adds ensures that the timers are updated each time the values in the mmap'd page are updated. Signed-off-by: Eric B Munson <emunson@mgebm.net> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1308932786-5111-1-git-send-email-emunson@mgebm.net Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/events/core.c')
-rw-r--r--kernel/events/core.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index c851d707821f..270e32f9fc06 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3372,8 +3372,19 @@ void perf_event_update_userpage(struct perf_event *event)
3372{ 3372{
3373 struct perf_event_mmap_page *userpg; 3373 struct perf_event_mmap_page *userpg;
3374 struct ring_buffer *rb; 3374 struct ring_buffer *rb;
3375 u64 enabled, running;
3375 3376
3376 rcu_read_lock(); 3377 rcu_read_lock();
3378 /*
3379 * compute total_time_enabled, total_time_running
3380 * based on snapshot values taken when the event
3381 * was last scheduled in.
3382 *
3383 * we cannot simply called update_context_time()
3384 * because of locking issue as we can be called in
3385 * NMI context
3386 */
3387 calc_timer_values(event, &enabled, &running);
3377 rb = rcu_dereference(event->rb); 3388 rb = rcu_dereference(event->rb);
3378 if (!rb) 3389 if (!rb)
3379 goto unlock; 3390 goto unlock;
@@ -3392,10 +3403,10 @@ void perf_event_update_userpage(struct perf_event *event)
3392 if (event->state == PERF_EVENT_STATE_ACTIVE) 3403 if (event->state == PERF_EVENT_STATE_ACTIVE)
3393 userpg->offset -= local64_read(&event->hw.prev_count); 3404 userpg->offset -= local64_read(&event->hw.prev_count);
3394 3405
3395 userpg->time_enabled = event->total_time_enabled + 3406 userpg->time_enabled = enabled +
3396 atomic64_read(&event->child_total_time_enabled); 3407 atomic64_read(&event->child_total_time_enabled);
3397 3408
3398 userpg->time_running = event->total_time_running + 3409 userpg->time_running = running +
3399 atomic64_read(&event->child_total_time_running); 3410 atomic64_read(&event->child_total_time_running);
3400 3411
3401 barrier(); 3412 barrier();