Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -369,6 +369,8 @@ enum perf_event_type {
	 *
	 *	{ u64			nr,
	 *	  u64			ips[nr];  } && PERF_SAMPLE_CALLCHAIN
	 *	{ u32			size;
	 *	  char                  data[size];}&& PERF_SAMPLE_RAW
	 * };
	 */
	PERF_EVENT_SAMPLE		= 9,
+2 −1
Original line number Diff line number Diff line
@@ -685,7 +685,8 @@ static void ftrace_profile_##call(proto) \
	pc = preempt_count();						\
									\
	__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 {								\
		char raw_data[__entry_size];				\
+24 −6
Original line number Diff line number Diff line
@@ -2646,7 +2646,6 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
		u64 counter;
	} group_entry;
	struct perf_callchain_entry *callchain = NULL;
	struct perf_raw_record *raw = NULL;
	int callchain_size = 0;
	u64 time;
	struct {
@@ -2716,9 +2715,15 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
	}

	if (sample_type & PERF_SAMPLE_RAW) {
		raw = data->raw;
		if (raw)
			header.size += raw->size;
		int size = sizeof(u32);

		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);
@@ -2784,8 +2789,21 @@ static void perf_counter_output(struct perf_counter *counter, int nmi,
		}
	}

	if ((sample_type & PERF_SAMPLE_RAW) && raw)
		perf_output_copy(&handle, raw->data, raw->size);
	if (sample_type & PERF_SAMPLE_RAW) {
		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);
}