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

Commit 74eec26f authored by Andrew Vagin's avatar Andrew Vagin Committed by Arnaldo Carvalho de Melo
Browse files

perf tools: Add ability to synthesize event according to a sample



It's the counterpart of perf_session__parse_sample.

v2: fixed mistakes found by David Ahern.
v3: s/data/sample/
    s/perf_event__change_sample/perf_event__synthesize_sample

Reviewed-by: default avatarDavid Ahern <dsahern@gmail.com>
Cc: Arun Sharma <asharma@fb.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: devel@openvz.org
Link: http://lkml.kernel.org/r/1323266161-394927-3-git-send-email-avagin@openvz.org


Signed-off-by: default avatarAndrew Vagin <avagin@openvz.org>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 317df650
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -199,6 +199,9 @@ const char *perf_event__name(unsigned int id);
int perf_event__parse_sample(const union perf_event *event, u64 type,
			     int sample_size, bool sample_id_all,
			     struct perf_sample *sample, bool swapped);
int perf_event__synthesize_sample(union perf_event *event, u64 type,
				  const struct perf_sample *sample,
				  bool swapped);

size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp);
size_t perf_event__fprintf_mmap(union perf_event *event, FILE *fp);
+79 −0
Original line number Diff line number Diff line
@@ -574,3 +574,82 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,

	return 0;
}

int perf_event__synthesize_sample(union perf_event *event, u64 type,
				  const struct perf_sample *sample,
				  bool swapped)
{
	u64 *array;

	/*
	 * used for cross-endian analysis. See git commit 65014ab3
	 * for why this goofiness is needed.
	 */
	union {
		u64 val64;
		u32 val32[2];
	} u;

	array = event->sample.array;

	if (type & PERF_SAMPLE_IP) {
		event->ip.ip = sample->ip;
		array++;
	}

	if (type & PERF_SAMPLE_TID) {
		u.val32[0] = sample->pid;
		u.val32[1] = sample->tid;
		if (swapped) {
			/*
			 * Inverse of what is done in perf_event__parse_sample
			 */
			u.val32[0] = bswap_32(u.val32[0]);
			u.val32[1] = bswap_32(u.val32[1]);
			u.val64 = bswap_64(u.val64);
		}

		*array = u.val64;
		array++;
	}

	if (type & PERF_SAMPLE_TIME) {
		*array = sample->time;
		array++;
	}

	if (type & PERF_SAMPLE_ADDR) {
		*array = sample->addr;
		array++;
	}

	if (type & PERF_SAMPLE_ID) {
		*array = sample->id;
		array++;
	}

	if (type & PERF_SAMPLE_STREAM_ID) {
		*array = sample->stream_id;
		array++;
	}

	if (type & PERF_SAMPLE_CPU) {
		u.val32[0] = sample->cpu;
		if (swapped) {
			/*
			 * Inverse of what is done in perf_event__parse_sample
			 */
			u.val32[0] = bswap_32(u.val32[0]);
			u.val64 = bswap_64(u.val64);
		}
		*array = u.val64;
		array++;
	}

	if (type & PERF_SAMPLE_PERIOD) {
		*array = sample->period;
		array++;
	}

	return 0;
}
+8 −0
Original line number Diff line number Diff line
@@ -134,6 +134,14 @@ static inline int perf_session__parse_sample(struct perf_session *session,
					session->header.needs_swap);
}

static inline int perf_session__synthesize_sample(struct perf_session *session,
						  union perf_event *event,
						  const struct perf_sample *sample)
{
	return perf_event__synthesize_sample(event, session->sample_type,
					     sample, session->header.needs_swap);
}

struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
					    unsigned int type);