Commit a044560c authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar

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: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Acked-by: default avatarFrederic 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: default avatarIngo Molnar <mingo@elte.hu>
parent c0a8865e
...@@ -369,6 +369,8 @@ enum perf_event_type { ...@@ -369,6 +369,8 @@ enum perf_event_type {
* *
* { u64 nr, * { u64 nr,
* u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN * u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN
* { u32 size;
* char data[size];}&& PERF_SAMPLE_RAW
* }; * };
*/ */
PERF_EVENT_SAMPLE = 9, PERF_EVENT_SAMPLE = 9,
......
...@@ -685,7 +685,8 @@ static void ftrace_profile_##call(proto) \ ...@@ -685,7 +685,8 @@ static void ftrace_profile_##call(proto) \
pc = preempt_count(); \ pc = preempt_count(); \
\ \
__data_size = ftrace_get_offsets_##call(&__data_offsets, args); \ __data_size = ftrace_get_offsets_##call(&__data_offsets, args); \
__entry_size = ALIGN(__data_size + sizeof(*entry), sizeof(u64));\ __entry_size = ALIGN(__data_size + sizeof(*entry) + sizeof(u32),\
sizeof(u64)); \
\ \
do { \ do { \
char raw_data[__entry_size]; \ char raw_data[__entry_size]; \
......
...@@ -2646,7 +2646,6 @@ static void perf_counter_output(struct perf_counter *counter, int nmi, ...@@ -2646,7 +2646,6 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
u64 counter; u64 counter;
} group_entry; } group_entry;
struct perf_callchain_entry *callchain = NULL; struct perf_callchain_entry *callchain = NULL;
struct perf_raw_record *raw = NULL;
int callchain_size = 0; int callchain_size = 0;
u64 time; u64 time;
struct { struct {
...@@ -2716,9 +2715,15 @@ static void perf_counter_output(struct perf_counter *counter, int nmi, ...@@ -2716,9 +2715,15 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
} }
if (sample_type & PERF_SAMPLE_RAW) { if (sample_type & PERF_SAMPLE_RAW) {
raw = data->raw; int size = sizeof(u32);
if (raw)
header.size += raw->size; if (data->raw)
size += data->raw->size;
else
size += sizeof(u32);
WARN_ON_ONCE(size & (sizeof(u64)-1));
header.size += size;
} }
ret = perf_output_begin(&handle, counter, header.size, nmi, 1); 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,8 +2789,21 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
} }
} }
if ((sample_type & PERF_SAMPLE_RAW) && raw) if (sample_type & PERF_SAMPLE_RAW) {
perf_output_copy(&handle, raw->data, raw->size); if (data->raw) {
perf_output_put(&handle, data->raw->size);
perf_output_copy(&handle, data->raw->data, data->raw->size);
} else {
struct {
u32 size;
u32 data;
} raw = {
.size = sizeof(u32),
.data = 0,
};
perf_output_put(&handle, raw);
}
}
perf_output_end(&handle); perf_output_end(&handle);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment