diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-06-10 15:02:22 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-06-10 20:39:02 -0400 |
commit | df1a132bf3d3508f863336c80a27806a2ac947e0 (patch) | |
tree | 2aa26b9c5d0528e816a80bd3b58c9b2442670d5c /kernel/perf_counter.c | |
parent | ea1900e571d40a3ce60c835c2f21e1fd8c5cb663 (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/perf_counter.c')
-rw-r--r-- | kernel/perf_counter.c | 38 |
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 | ||
2381 | static void perf_counter_output(struct perf_counter *counter, | 2381 | static 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 | ||
2953 | int perf_counter_overflow(struct perf_counter *counter, | 2953 | int 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) | |||
3054 | static enum hrtimer_restart perf_swcounter_hrtimer(struct hrtimer *hrtimer) | 3054 | static 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) | |||
3084 | static void perf_swcounter_overflow(struct perf_counter *counter, | 3085 | static 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 | ||