aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/events
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2011-11-21 05:43:53 -0500
committerIngo Molnar <mingo@elte.hu>2011-12-21 05:01:13 -0500
commite3f3541c19c89a4daae39300defba68943301949 (patch)
treef3d6fe5c39dfee8045e7955e5637ae9ff9c0d4d5 /kernel/events
parent0c9d42ed4cee2aa1dfc3a260b741baae8615744f (diff)
perf: Extend the mmap control page with time (TSC) fields
Extend the mmap control page with fields so that userspace can compute time deltas relative to the provided time fields. Currently only implemented for x86 with constant and nonstop TSC. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Stephane Eranian <eranian@google.com> Cc: Arun Sharma <asharma@fb.com> Link: http://lkml.kernel.org/n/tip-3u1jucza77j3wuvs0x2bic0f@git.kernel.org Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/events')
-rw-r--r--kernel/events/core.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/kernel/events/core.c b/kernel/events/core.c
index dcd4049e92fc..3a9c7d81afbf 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3220,17 +3220,22 @@ static int perf_event_index(struct perf_event *event)
3220} 3220}
3221 3221
3222static void calc_timer_values(struct perf_event *event, 3222static void calc_timer_values(struct perf_event *event,
3223 u64 *now,
3223 u64 *enabled, 3224 u64 *enabled,
3224 u64 *running) 3225 u64 *running)
3225{ 3226{
3226 u64 now, ctx_time; 3227 u64 ctx_time;
3227 3228
3228 now = perf_clock(); 3229 *now = perf_clock();
3229 ctx_time = event->shadow_ctx_time + now; 3230 ctx_time = event->shadow_ctx_time + *now;
3230 *enabled = ctx_time - event->tstamp_enabled; 3231 *enabled = ctx_time - event->tstamp_enabled;
3231 *running = ctx_time - event->tstamp_running; 3232 *running = ctx_time - event->tstamp_running;
3232} 3233}
3233 3234
3235void __weak perf_update_user_clock(struct perf_event_mmap_page *userpg, u64 now)
3236{
3237}
3238
3234/* 3239/*
3235 * Callers need to ensure there can be no nesting of this function, otherwise 3240 * Callers need to ensure there can be no nesting of this function, otherwise
3236 * the seqlock logic goes bad. We can not serialize this because the arch 3241 * the seqlock logic goes bad. We can not serialize this because the arch
@@ -3240,7 +3245,7 @@ void perf_event_update_userpage(struct perf_event *event)
3240{ 3245{
3241 struct perf_event_mmap_page *userpg; 3246 struct perf_event_mmap_page *userpg;
3242 struct ring_buffer *rb; 3247 struct ring_buffer *rb;
3243 u64 enabled, running; 3248 u64 enabled, running, now;
3244 3249
3245 rcu_read_lock(); 3250 rcu_read_lock();
3246 /* 3251 /*
@@ -3252,7 +3257,7 @@ void perf_event_update_userpage(struct perf_event *event)
3252 * because of locking issue as we can be called in 3257 * because of locking issue as we can be called in
3253 * NMI context 3258 * NMI context
3254 */ 3259 */
3255 calc_timer_values(event, &enabled, &running); 3260 calc_timer_values(event, &now, &enabled, &running);
3256 rb = rcu_dereference(event->rb); 3261 rb = rcu_dereference(event->rb);
3257 if (!rb) 3262 if (!rb)
3258 goto unlock; 3263 goto unlock;
@@ -3277,6 +3282,8 @@ void perf_event_update_userpage(struct perf_event *event)
3277 userpg->time_running = running + 3282 userpg->time_running = running +
3278 atomic64_read(&event->child_total_time_running); 3283 atomic64_read(&event->child_total_time_running);
3279 3284
3285 perf_update_user_clock(userpg, now);
3286
3280 barrier(); 3287 barrier();
3281 ++userpg->lock; 3288 ++userpg->lock;
3282 preempt_enable(); 3289 preempt_enable();
@@ -3763,7 +3770,7 @@ static void perf_output_read_group(struct perf_output_handle *handle,
3763static void perf_output_read(struct perf_output_handle *handle, 3770static void perf_output_read(struct perf_output_handle *handle,
3764 struct perf_event *event) 3771 struct perf_event *event)
3765{ 3772{
3766 u64 enabled = 0, running = 0; 3773 u64 enabled = 0, running = 0, now;
3767 u64 read_format = event->attr.read_format; 3774 u64 read_format = event->attr.read_format;
3768 3775
3769 /* 3776 /*
@@ -3776,7 +3783,7 @@ static void perf_output_read(struct perf_output_handle *handle,
3776 * NMI context 3783 * NMI context
3777 */ 3784 */
3778 if (read_format & PERF_FORMAT_TOTAL_TIMES) 3785 if (read_format & PERF_FORMAT_TOTAL_TIMES)
3779 calc_timer_values(event, &enabled, &running); 3786 calc_timer_values(event, &now, &enabled, &running);
3780 3787
3781 if (event->attr.read_format & PERF_FORMAT_GROUP) 3788 if (event->attr.read_format & PERF_FORMAT_GROUP)
3782 perf_output_read_group(handle, event, enabled, running); 3789 perf_output_read_group(handle, event, enabled, running);