diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2010-03-03 09:55:04 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2010-03-10 07:22:23 -0500 |
commit | dc1d628a67a8f042e711ea5accc0beedc3ef0092 (patch) | |
tree | 728f72a5f9a8368b225890a95ea947c1c8cda301 /kernel/perf_event.c | |
parent | 548b84166917d6f5e2296123b85ad24aecd3801d (diff) |
perf: Provide generic perf_sample_data initialization
This makes it easier to extend perf_sample_data and fixes a bug on arm
and sparc, which failed to set ->raw to NULL, which can cause crashes
when combined with PERF_SAMPLE_RAW.
It also optimizes PowerPC and tracepoint, because the struct
initialization is forced to zero out the whole structure.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Jean Pihet <jpihet@mvista.com>
Reviewed-by: Frederic Weisbecker <fweisbec@gmail.com>
Acked-by: David S. Miller <davem@davemloft.net>
Cc: Jamie Iles <jamie.iles@picochip.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: stable@kernel.org
LKML-Reference: <20100304140100.315416040@chello.nl>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel/perf_event.c')
-rw-r--r-- | kernel/perf_event.c | 21 |
1 files changed, 8 insertions, 13 deletions
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index e68745053013..4393b9e73740 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -4108,8 +4108,7 @@ void __perf_sw_event(u32 event_id, u64 nr, int nmi, | |||
4108 | if (rctx < 0) | 4108 | if (rctx < 0) |
4109 | return; | 4109 | return; |
4110 | 4110 | ||
4111 | data.addr = addr; | 4111 | perf_sample_data_init(&data, addr); |
4112 | data.raw = NULL; | ||
4113 | 4112 | ||
4114 | do_perf_sw_event(PERF_TYPE_SOFTWARE, event_id, nr, nmi, &data, regs); | 4113 | do_perf_sw_event(PERF_TYPE_SOFTWARE, event_id, nr, nmi, &data, regs); |
4115 | 4114 | ||
@@ -4154,11 +4153,10 @@ static enum hrtimer_restart perf_swevent_hrtimer(struct hrtimer *hrtimer) | |||
4154 | struct perf_event *event; | 4153 | struct perf_event *event; |
4155 | u64 period; | 4154 | u64 period; |
4156 | 4155 | ||
4157 | event = container_of(hrtimer, struct perf_event, hw.hrtimer); | 4156 | event = container_of(hrtimer, struct perf_event, hw.hrtimer); |
4158 | event->pmu->read(event); | 4157 | event->pmu->read(event); |
4159 | 4158 | ||
4160 | data.addr = 0; | 4159 | perf_sample_data_init(&data, 0); |
4161 | data.raw = NULL; | ||
4162 | data.period = event->hw.last_period; | 4160 | data.period = event->hw.last_period; |
4163 | regs = get_irq_regs(); | 4161 | regs = get_irq_regs(); |
4164 | /* | 4162 | /* |
@@ -4322,17 +4320,15 @@ static const struct pmu perf_ops_task_clock = { | |||
4322 | void perf_tp_event(int event_id, u64 addr, u64 count, void *record, | 4320 | void perf_tp_event(int event_id, u64 addr, u64 count, void *record, |
4323 | int entry_size) | 4321 | int entry_size) |
4324 | { | 4322 | { |
4323 | struct pt_regs *regs = get_irq_regs(); | ||
4324 | struct perf_sample_data data; | ||
4325 | struct perf_raw_record raw = { | 4325 | struct perf_raw_record raw = { |
4326 | .size = entry_size, | 4326 | .size = entry_size, |
4327 | .data = record, | 4327 | .data = record, |
4328 | }; | 4328 | }; |
4329 | 4329 | ||
4330 | struct perf_sample_data data = { | 4330 | perf_sample_data_init(&data, addr); |
4331 | .addr = addr, | 4331 | data.raw = &raw; |
4332 | .raw = &raw, | ||
4333 | }; | ||
4334 | |||
4335 | struct pt_regs *regs = get_irq_regs(); | ||
4336 | 4332 | ||
4337 | if (!regs) | 4333 | if (!regs) |
4338 | regs = task_pt_regs(current); | 4334 | regs = task_pt_regs(current); |
@@ -4448,8 +4444,7 @@ void perf_bp_event(struct perf_event *bp, void *data) | |||
4448 | struct perf_sample_data sample; | 4444 | struct perf_sample_data sample; |
4449 | struct pt_regs *regs = data; | 4445 | struct pt_regs *regs = data; |
4450 | 4446 | ||
4451 | sample.raw = NULL; | 4447 | perf_sample_data_init(&sample, bp->attr.bp_addr); |
4452 | sample.addr = bp->attr.bp_addr; | ||
4453 | 4448 | ||
4454 | if (!perf_exclude_event(bp, regs)) | 4449 | if (!perf_exclude_event(bp, regs)) |
4455 | perf_swevent_add(bp, 1, 1, &sample, regs); | 4450 | perf_swevent_add(bp, 1, 1, &sample, regs); |