diff options
author | Peter Zijlstra <a.p.zijlstra@chello.nl> | 2009-08-10 05:16:52 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-08-10 05:33:09 -0400 |
commit | a044560c3a1f0ad75ce685c1ed7604820b9ed319 (patch) | |
tree | 51fa4979ad02d388b35e1a56020bfbd8c2e5329d /kernel | |
parent | c0a8865e32c8d1a562db38e06ef31ef23282f646 (diff) |
perf_counter: Correct PERF_SAMPLE_RAW output
PERF_SAMPLE_* output switches should unconditionally output the
correct format, as they are the only way to unambiguously parse
the PERF_EVENT_SAMPLE data.
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1249896447.17467.74.camel@twins>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/perf_counter.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/kernel/perf_counter.c b/kernel/perf_counter.c index 546e62d62941..5229d1666fa5 100644 --- a/kernel/perf_counter.c +++ b/kernel/perf_counter.c | |||
@@ -2646,7 +2646,6 @@ static void perf_counter_output(struct perf_counter *counter, int nmi, | |||
2646 | u64 counter; | 2646 | u64 counter; |
2647 | } group_entry; | 2647 | } group_entry; |
2648 | struct perf_callchain_entry *callchain = NULL; | 2648 | struct perf_callchain_entry *callchain = NULL; |
2649 | struct perf_raw_record *raw = NULL; | ||
2650 | int callchain_size = 0; | 2649 | int callchain_size = 0; |
2651 | u64 time; | 2650 | u64 time; |
2652 | struct { | 2651 | struct { |
@@ -2716,9 +2715,15 @@ static void perf_counter_output(struct perf_counter *counter, int nmi, | |||
2716 | } | 2715 | } |
2717 | 2716 | ||
2718 | if (sample_type & PERF_SAMPLE_RAW) { | 2717 | if (sample_type & PERF_SAMPLE_RAW) { |
2719 | raw = data->raw; | 2718 | int size = sizeof(u32); |
2720 | if (raw) | 2719 | |
2721 | header.size += raw->size; | 2720 | if (data->raw) |
2721 | size += data->raw->size; | ||
2722 | else | ||
2723 | size += sizeof(u32); | ||
2724 | |||
2725 | WARN_ON_ONCE(size & (sizeof(u64)-1)); | ||
2726 | header.size += size; | ||
2722 | } | 2727 | } |
2723 | 2728 | ||
2724 | ret = perf_output_begin(&handle, counter, header.size, nmi, 1); | 2729 | ret = perf_output_begin(&handle, counter, header.size, nmi, 1); |
@@ -2784,8 +2789,21 @@ static void perf_counter_output(struct perf_counter *counter, int nmi, | |||
2784 | } | 2789 | } |
2785 | } | 2790 | } |
2786 | 2791 | ||
2787 | if ((sample_type & PERF_SAMPLE_RAW) && raw) | 2792 | if (sample_type & PERF_SAMPLE_RAW) { |
2788 | perf_output_copy(&handle, raw->data, raw->size); | 2793 | if (data->raw) { |
2794 | perf_output_put(&handle, data->raw->size); | ||
2795 | perf_output_copy(&handle, data->raw->data, data->raw->size); | ||
2796 | } else { | ||
2797 | struct { | ||
2798 | u32 size; | ||
2799 | u32 data; | ||
2800 | } raw = { | ||
2801 | .size = sizeof(u32), | ||
2802 | .data = 0, | ||
2803 | }; | ||
2804 | perf_output_put(&handle, raw); | ||
2805 | } | ||
2806 | } | ||
2789 | 2807 | ||
2790 | perf_output_end(&handle); | 2808 | perf_output_end(&handle); |
2791 | } | 2809 | } |