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

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

perf: Convert perf event types into event type events



Bypasses the event type 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-7-git-send-email-tzanussi@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 2c46dbb5
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -592,6 +592,13 @@ static int __cmd_record(int argc, const char **argv)
			pr_err("Couldn't synthesize attrs.\n");
			return err;
		}

		err = event__synthesize_event_types(process_synthesized_event,
						    session);
		if (err < 0) {
			pr_err("Couldn't synthesize event_types.\n");
			return err;
		}
	}

	err = event__synthesize_kernel_mmap(process_synthesized_event,
+1 −0
Original line number Diff line number Diff line
@@ -268,6 +268,7 @@ static struct perf_event_ops event_ops = {
	.lost	= event__process_lost,
	.read	= process_read_event,
	.attr	= event__process_attr,
	.event_type = event__process_event_type,
};

extern volatile int session_done;
+1 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ static struct perf_event_ops event_ops = {
	.sample	= process_sample_event,
	.comm	= event__process_comm,
	.attr	= event__process_attr,
	.event_type = event__process_event_type,
};

extern volatile int session_done;
+14 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ struct build_id_event {

enum perf_header_event_type { /* above any possible kernel type */
	PERF_RECORD_HEADER_ATTR			= 64,
	PERF_RECORD_HEADER_EVENT_TYPE		= 65,
	PERF_RECORD_HEADER_MAX
};

@@ -94,6 +95,18 @@ struct attr_event {
	u64 id[];
};

#define MAX_EVENT_NAME 64

struct perf_trace_event_type {
	u64	event_id;
	char	name[MAX_EVENT_NAME];
};

struct event_type_event {
	struct perf_event_header header;
	struct perf_trace_event_type event_type;
};

typedef union event_union {
	struct perf_event_header	header;
	struct ip_event			ip;
@@ -104,6 +117,7 @@ typedef union event_union {
	struct read_event		read;
	struct sample_event		sample;
	struct attr_event		attr;
	struct event_type_event		event_type;
} event_t;

struct events_stats {
+55 −7
Original line number Diff line number Diff line
@@ -99,13 +99,6 @@ int perf_header__add_attr(struct perf_header *self,
	return 0;
}

#define MAX_EVENT_NAME 64

struct perf_trace_event_type {
	u64	event_id;
	char	name[MAX_EVENT_NAME];
};

static int event_count;
static struct perf_trace_event_type *events;

@@ -886,3 +879,58 @@ int event__process_attr(event_t *self, struct perf_session *session)

	return 0;
}

int event__synthesize_event_type(u64 event_id, char *name,
				 event__handler_t process,
				 struct perf_session *session)
{
	event_t ev;
	size_t size = 0;
	int err = 0;

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

	ev.event_type.event_type.event_id = event_id;
	memset(ev.event_type.event_type.name, 0, MAX_EVENT_NAME);
	strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1);

	ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE;
	size = strlen(name);
	size = ALIGN(size, sizeof(u64));
	ev.event_type.header.size = sizeof(ev.event_type) -
		(sizeof(ev.event_type.event_type.name) - size);

	err = process(&ev, session);

	return err;
}

int event__synthesize_event_types(event__handler_t process,
				  struct perf_session *session)
{
	struct perf_trace_event_type *type;
	int i, err = 0;

	for (i = 0; i < event_count; i++) {
		type = &events[i];

		err = event__synthesize_event_type(type->event_id, type->name,
						   process, session);
		if (err) {
			pr_debug("failed to create perf header event type\n");
			return err;
		}
	}

	return err;
}

int event__process_event_type(event_t *self,
			      struct perf_session *session __unused)
{
	if (perf_header__push_event(self->event_type.event_type.event_id,
				    self->event_type.event_type.name) < 0)
		return -ENOMEM;

	return 0;
}
Loading