aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPeter Zijlstra <a.p.zijlstra@chello.nl>2009-06-10 15:02:22 -0400
committerIngo Molnar <mingo@elte.hu>2009-06-10 20:39:02 -0400
commitdf1a132bf3d3508f863336c80a27806a2ac947e0 (patch)
tree2aa26b9c5d0528e816a80bd3b58c9b2442670d5c /kernel
parentea1900e571d40a3ce60c835c2f21e1fd8c5cb663 (diff)
perf_counter: Introduce struct for sample data
For easy extension of the sample data, put it in a structure. Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> LKML-Reference: <new-submission> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/perf_counter.c38
1 files changed, 22 insertions, 16 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c
index ae591a1275a6..4fe85e804f43 100644
--- a/kernel/perf_counter.c
+++ b/kernel/perf_counter.c
@@ -2378,8 +2378,8 @@ static u32 perf_counter_tid(struct perf_counter *counter, struct task_struct *p)
2378 return task_pid_nr_ns(p, counter->ns); 2378 return task_pid_nr_ns(p, counter->ns);
2379} 2379}
2380 2380
2381static void perf_counter_output(struct perf_counter *counter, 2381static void perf_counter_output(struct perf_counter *counter, int nmi,
2382 int nmi, struct pt_regs *regs, u64 addr) 2382 struct perf_sample_data *data)
2383{ 2383{
2384 int ret; 2384 int ret;
2385 u64 sample_type = counter->attr.sample_type; 2385 u64 sample_type = counter->attr.sample_type;
@@ -2404,10 +2404,10 @@ static void perf_counter_output(struct perf_counter *counter,
2404 header.size = sizeof(header); 2404 header.size = sizeof(header);
2405 2405
2406 header.misc = PERF_EVENT_MISC_OVERFLOW; 2406 header.misc = PERF_EVENT_MISC_OVERFLOW;
2407 header.misc |= perf_misc_flags(regs); 2407 header.misc |= perf_misc_flags(data->regs);
2408 2408
2409 if (sample_type & PERF_SAMPLE_IP) { 2409 if (sample_type & PERF_SAMPLE_IP) {
2410 ip = perf_instruction_pointer(regs); 2410 ip = perf_instruction_pointer(data->regs);
2411 header.type |= PERF_SAMPLE_IP; 2411 header.type |= PERF_SAMPLE_IP;
2412 header.size += sizeof(ip); 2412 header.size += sizeof(ip);
2413 } 2413 }
@@ -2460,7 +2460,7 @@ static void perf_counter_output(struct perf_counter *counter,
2460 } 2460 }
2461 2461
2462 if (sample_type & PERF_SAMPLE_CALLCHAIN) { 2462 if (sample_type & PERF_SAMPLE_CALLCHAIN) {
2463 callchain = perf_callchain(regs); 2463 callchain = perf_callchain(data->regs);
2464 2464
2465 if (callchain) { 2465 if (callchain) {
2466 callchain_size = (1 + callchain->nr) * sizeof(u64); 2466 callchain_size = (1 + callchain->nr) * sizeof(u64);
@@ -2486,7 +2486,7 @@ static void perf_counter_output(struct perf_counter *counter,
2486 perf_output_put(&handle, time); 2486 perf_output_put(&handle, time);
2487 2487
2488 if (sample_type & PERF_SAMPLE_ADDR) 2488 if (sample_type & PERF_SAMPLE_ADDR)
2489 perf_output_put(&handle, addr); 2489 perf_output_put(&handle, data->addr);
2490 2490
2491 if (sample_type & PERF_SAMPLE_ID) 2491 if (sample_type & PERF_SAMPLE_ID)
2492 perf_output_put(&handle, counter->id); 2492 perf_output_put(&handle, counter->id);
@@ -2950,8 +2950,8 @@ static void perf_log_throttle(struct perf_counter *counter, int enable)
2950 * Generic counter overflow handling. 2950 * Generic counter overflow handling.
2951 */ 2951 */
2952 2952
2953int perf_counter_overflow(struct perf_counter *counter, 2953int perf_counter_overflow(struct perf_counter *counter, int nmi,
2954 int nmi, struct pt_regs *regs, u64 addr) 2954 struct perf_sample_data *data)
2955{ 2955{
2956 int events = atomic_read(&counter->event_limit); 2956 int events = atomic_read(&counter->event_limit);
2957 int throttle = counter->pmu->unthrottle != NULL; 2957 int throttle = counter->pmu->unthrottle != NULL;
@@ -3005,7 +3005,7 @@ int perf_counter_overflow(struct perf_counter *counter,
3005 perf_counter_disable(counter); 3005 perf_counter_disable(counter);
3006 } 3006 }
3007 3007
3008 perf_counter_output(counter, nmi, regs, addr); 3008 perf_counter_output(counter, nmi, data);
3009 return ret; 3009 return ret;
3010} 3010}
3011 3011
@@ -3054,24 +3054,25 @@ static void perf_swcounter_set_period(struct perf_counter *counter)
3054static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) 3054static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer)
3055{ 3055{
3056 enum hrtimer_restart ret = HRTIMER_RESTART; 3056 enum hrtimer_restart ret = HRTIMER_RESTART;
3057 struct perf_sample_data data;
3057 struct perf_counter *counter; 3058 struct perf_counter *counter;
3058 struct pt_regs *regs;
3059 u64 period; 3059 u64 period;
3060 3060
3061 counter = container_of(hrtimer, struct perf_counter, hw.hrtimer); 3061 counter = container_of(hrtimer, struct perf_counter, hw.hrtimer);
3062 counter->pmu->read(counter); 3062 counter->pmu->read(counter);
3063 3063
3064 regs = get_irq_regs(); 3064 data.addr = 0;
3065 data.regs = get_irq_regs();
3065 /* 3066 /*
3066 * In case we exclude kernel IPs or are somehow not in interrupt 3067 * In case we exclude kernel IPs or are somehow not in interrupt
3067 * context, provide the next best thing, the user IP. 3068 * context, provide the next best thing, the user IP.
3068 */ 3069 */
3069 if ((counter->attr.exclude_kernel || !regs) && 3070 if ((counter->attr.exclude_kernel || !data.regs) &&
3070 !counter->attr.exclude_user) 3071 !counter->attr.exclude_user)
3071 regs = task_pt_regs(current); 3072 data.regs = task_pt_regs(current);
3072 3073
3073 if (regs) { 3074 if (data.regs) {
3074 if (perf_counter_overflow(counter, 0, regs, 0)) 3075 if (perf_counter_overflow(counter, 0, &data))
3075 ret = HRTIMER_NORESTART; 3076 ret = HRTIMER_NORESTART;
3076 } 3077 }
3077 3078
@@ -3084,9 +3085,14 @@ static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer)
3084static void perf_swcounter_overflow(struct perf_counter *counter, 3085static void perf_swcounter_overflow(struct perf_counter *counter,
3085 int nmi, struct pt_regs *regs, u64 addr) 3086 int nmi, struct pt_regs *regs, u64 addr)
3086{ 3087{
3088 struct perf_sample_data data = {
3089 .regs = regs,
3090 .addr = addr,
3091 };
3092
3087 perf_swcounter_update(counter); 3093 perf_swcounter_update(counter);
3088 perf_swcounter_set_period(counter); 3094 perf_swcounter_set_period(counter);
3089 if (perf_counter_overflow(counter, nmi, regs, addr)) 3095 if (perf_counter_overflow(counter, nmi, &data))
3090 /* soft-disable the counter */ 3096 /* soft-disable the counter */
3091 ; 3097 ;
3092 3098