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

Commit c7929e47 authored by Tom Zanussi's avatar Tom Zanussi Committed by Ingo Molnar
Browse files

perf: Convert perf header build_ids into build_id events



Bypasses the build_id perf header code and replaces it with a
synthesized event and processing function that accomplishes the
same thing, used when reading/writing perf data to/from a pipe.

Signed-off-by: default avatarTom Zanussi <tzanussi@gmail.com>
Acked-by: default avatarThomas Gleixner <tglx@linutronix.de>
Cc: fweisbec@gmail.com
Cc: rostedt@goodmis.org
Cc: k-keiichi@bx.jp.nec.com
Cc: acme@ghostprotocols.net
LKML-Reference: <1270184365-8281-9-git-send-email-tzanussi@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 9215545e
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -426,10 +426,19 @@ static int process_buildids(void)

static void atexit_header(void)
{
	if (!pipe_output) {
		session->header.data_size += bytes_written;

		process_buildids();
		perf_header__write(&session->header, output, true);
	} else {
		int err;

		err = event__synthesize_build_ids(process_synthesized_event,
						  session);
		if (err < 0)
			pr_err("Couldn't synthesize build ids.\n");
	}
}

static int __cmd_record(int argc, const char **argv)
+1 −0
Original line number Diff line number Diff line
@@ -270,6 +270,7 @@ static struct perf_event_ops event_ops = {
	.attr	= event__process_attr,
	.event_type = event__process_event_type,
	.tracing_data = event__process_tracing_data,
	.build_id = event__process_build_id,
};

extern volatile int session_done;
+1 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ static struct perf_event_ops event_ops = {
	.attr	= event__process_attr,
	.event_type = event__process_event_type,
	.tracing_data = event__process_tracing_data,
	.build_id = event__process_build_id,
};

extern volatile int session_done;
+2 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ enum perf_header_event_type { /* above any possible kernel type */
	PERF_RECORD_HEADER_ATTR			= 64,
	PERF_RECORD_HEADER_EVENT_TYPE		= 65,
	PERF_RECORD_HEADER_TRACING_DATA		= 66,
	PERF_RECORD_HEADER_BUILD_ID		= 67,
	PERF_RECORD_HEADER_MAX
};

@@ -125,6 +126,7 @@ typedef union event_union {
	struct attr_event		attr;
	struct event_type_event		event_type;
	struct tracing_data_event	tracing_data;
	struct build_id_event		build_id;
} event_t;

struct events_stats {
+90 −0
Original line number Diff line number Diff line
@@ -986,3 +986,93 @@ int event__process_tracing_data(event_t *self,

	return size_read + padding;
}

int event__synthesize_build_id(struct dso *pos, u16 misc,
			       event__handler_t process,
			       struct perf_session *session)
{
	event_t ev;
	size_t len;
	int err = 0;

	if (!pos->hit)
		return err;

	memset(&ev, 0, sizeof(ev));

	len = pos->long_name_len + 1;
	len = ALIGN(len, NAME_ALIGN);
	memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id));
	ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID;
	ev.build_id.header.misc = misc;
	ev.build_id.header.size = sizeof(ev.build_id) + len;
	memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);

	err = process(&ev, session);

	return err;
}

static int __event_synthesize_build_ids(struct list_head *head, u16 misc,
					event__handler_t process,
					struct perf_session *session)
{
	struct dso *pos;

	dsos__for_each_with_build_id(pos, head) {
		int err;
		if (!pos->hit)
			continue;

		err = event__synthesize_build_id(pos, misc, process, session);
		if (err < 0)
			return err;
	}

	return 0;
}

int event__synthesize_build_ids(event__handler_t process,
				struct perf_session *session)
{
	int err;

	if (!dsos__read_build_ids(true))
		return 0;

	err = __event_synthesize_build_ids(&dsos__kernel,
					   PERF_RECORD_MISC_KERNEL,
					   process, session);
	if (err == 0)
		err = __event_synthesize_build_ids(&dsos__user,
						   PERF_RECORD_MISC_USER,
						   process, session);

	if (err < 0) {
		pr_debug("failed to synthesize build ids\n");
		return err;
	}

	dsos__cache_build_ids();

	return 0;
}

int event__process_build_id(event_t *self,
			    struct perf_session *session __unused)
{
	struct list_head *head = &dsos__user;
	struct dso *dso;

	if (self->build_id.header.misc & PERF_RECORD_MISC_KERNEL)
		head = &dsos__kernel;

	dso = __dsos__findnew(head, self->build_id.filename);
	if (dso != NULL) {
		dso__set_build_id(dso, &self->build_id.build_id);
		if (head == &dsos__kernel && self->build_id.filename[0] == '[')
			dso->kernel = 1;
	}

	return 0;
}
Loading