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

Commit a16ac023 authored by Adrian Hunter's avatar Adrian Hunter Committed by Arnaldo Carvalho de Melo
Browse files

perf tools: Add user events for AUX area tracing



Add two user events for AUX area tracing.

PERF_RECORD_AUXTRACE_INFO contains metadata, consisting primarily the
type of the AUX area tracing data plus some amount of
architecture-specific information.  There should be only one
PERF_RECORD_AUXTRACE_INFO event.

PERF_RECORD_AUXTRACE identifies AUX area tracing data copied from the
mmapped AUX area tracing region.  The actual data is not part of the
event but immediately follows it.

Signed-off-by: default avatarAdrian Hunter <adrian.hunter@intel.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1428594864-29309-4-git-send-email-adrian.hunter@intel.com


[ s/MIN/min/g and use cast to fix up wrt -Werror=sign-compare till we adopt min_t() ]
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 718c602d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -29,6 +29,8 @@ static const char *perf_event__names[] = {
	[PERF_RECORD_HEADER_BUILD_ID]		= "BUILD_ID",
	[PERF_RECORD_FINISHED_ROUND]		= "FINISHED_ROUND",
	[PERF_RECORD_ID_INDEX]			= "ID_INDEX",
	[PERF_RECORD_AUXTRACE_INFO]		= "AUXTRACE_INFO",
	[PERF_RECORD_AUXTRACE]			= "AUXTRACE",
};

const char *perf_event__name(unsigned int id)
+22 −0
Original line number Diff line number Diff line
@@ -215,6 +215,8 @@ enum perf_user_event_type { /* above any possible kernel type */
	PERF_RECORD_HEADER_BUILD_ID		= 67,
	PERF_RECORD_FINISHED_ROUND		= 68,
	PERF_RECORD_ID_INDEX			= 69,
	PERF_RECORD_AUXTRACE_INFO		= 70,
	PERF_RECORD_AUXTRACE			= 71,
	PERF_RECORD_HEADER_MAX
};

@@ -280,6 +282,24 @@ struct id_index_event {
	struct id_index_entry entries[0];
};

struct auxtrace_info_event {
	struct perf_event_header header;
	u32 type;
	u32 reserved__; /* For alignment */
	u64 priv[];
};

struct auxtrace_event {
	struct perf_event_header header;
	u64 size;
	u64 offset;
	u64 reference;
	u32 idx;
	u32 tid;
	u32 cpu;
	u32 reserved__; /* For alignment */
};

union perf_event {
	struct perf_event_header	header;
	struct mmap_event		mmap;
@@ -295,6 +315,8 @@ union perf_event {
	struct tracing_data_event	tracing_data;
	struct build_id_event		build_id;
	struct id_index_event		id_index;
	struct auxtrace_info_event	auxtrace_info;
	struct auxtrace_event		auxtrace;
};

void perf_event__print_totals(void);
+69 −0
Original line number Diff line number Diff line
@@ -262,6 +262,40 @@ static int process_id_index_stub(struct perf_tool *tool __maybe_unused,
	return 0;
}

static int process_event_auxtrace_info_stub(struct perf_tool *tool __maybe_unused,
				union perf_event *event __maybe_unused,
				struct perf_session *session __maybe_unused)
{
	dump_printf(": unhandled!\n");
	return 0;
}

static int skipn(int fd, off_t n)
{
	char buf[4096];
	ssize_t ret;

	while (n > 0) {
		ret = read(fd, buf, min(n, (off_t)sizeof(buf)));
		if (ret <= 0)
			return ret;
		n -= ret;
	}

	return 0;
}

static s64 process_event_auxtrace_stub(struct perf_tool *tool __maybe_unused,
				       union perf_event *event,
				       struct perf_session *session
				       __maybe_unused)
{
	dump_printf(": unhandled!\n");
	if (perf_data_file__is_pipe(session->file))
		skipn(perf_data_file__fd(session->file), event->auxtrace.size);
	return event->auxtrace.size;
}

void perf_tool__fill_defaults(struct perf_tool *tool)
{
	if (tool->sample == NULL)
@@ -298,6 +332,10 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
	}
	if (tool->id_index == NULL)
		tool->id_index = process_id_index_stub;
	if (tool->auxtrace_info == NULL)
		tool->auxtrace_info = process_event_auxtrace_info_stub;
	if (tool->auxtrace == NULL)
		tool->auxtrace = process_event_auxtrace_stub;
}

static void swap_sample_id_all(union perf_event *event, void *data)
@@ -478,6 +516,29 @@ static void perf_event__tracing_data_swap(union perf_event *event,
	event->tracing_data.size = bswap_32(event->tracing_data.size);
}

static void perf_event__auxtrace_info_swap(union perf_event *event,
					   bool sample_id_all __maybe_unused)
{
	size_t size;

	event->auxtrace_info.type = bswap_32(event->auxtrace_info.type);

	size = event->header.size;
	size -= (void *)&event->auxtrace_info.priv - (void *)event;
	mem_bswap_64(event->auxtrace_info.priv, size);
}

static void perf_event__auxtrace_swap(union perf_event *event,
				      bool sample_id_all __maybe_unused)
{
	event->auxtrace.size      = bswap_64(event->auxtrace.size);
	event->auxtrace.offset    = bswap_64(event->auxtrace.offset);
	event->auxtrace.reference = bswap_64(event->auxtrace.reference);
	event->auxtrace.idx       = bswap_32(event->auxtrace.idx);
	event->auxtrace.tid       = bswap_32(event->auxtrace.tid);
	event->auxtrace.cpu       = bswap_32(event->auxtrace.cpu);
}

typedef void (*perf_event__swap_op)(union perf_event *event,
				    bool sample_id_all);

@@ -497,6 +558,8 @@ static perf_event__swap_op perf_event__swap_ops[] = {
	[PERF_RECORD_HEADER_TRACING_DATA] = perf_event__tracing_data_swap,
	[PERF_RECORD_HEADER_BUILD_ID]	  = NULL,
	[PERF_RECORD_ID_INDEX]		  = perf_event__all64_swap,
	[PERF_RECORD_AUXTRACE_INFO]	  = perf_event__auxtrace_info_swap,
	[PERF_RECORD_AUXTRACE]		  = perf_event__auxtrace_swap,
	[PERF_RECORD_HEADER_MAX]	  = NULL,
};

@@ -980,6 +1043,12 @@ static s64 perf_session__process_user_event(struct perf_session *session,
		return tool->finished_round(tool, event, oe);
	case PERF_RECORD_ID_INDEX:
		return tool->id_index(tool, event, session);
	case PERF_RECORD_AUXTRACE_INFO:
		return tool->auxtrace_info(tool, event, session);
	case PERF_RECORD_AUXTRACE:
		/* setup for reading amidst mmap */
		lseek(fd, file_offset + event->header.size, SEEK_SET);
		return tool->auxtrace(tool, event, session);
	default:
		return -EINVAL;
	}
+8 −1
Original line number Diff line number Diff line
@@ -3,6 +3,8 @@

#include <stdbool.h>

#include <linux/types.h>

struct perf_session;
union perf_event;
struct perf_evlist;
@@ -29,6 +31,9 @@ typedef int (*event_op2)(struct perf_tool *tool, union perf_event *event,
typedef int (*event_oe)(struct perf_tool *tool, union perf_event *event,
			struct ordered_events *oe);

typedef s64 (*event_op3)(struct perf_tool *tool, union perf_event *event,
			 struct perf_session *session);

struct perf_tool {
	event_sample	sample,
			read;
@@ -44,7 +49,9 @@ struct perf_tool {
	event_op2	tracing_data;
	event_oe	finished_round;
	event_op2	build_id,
			id_index;
			id_index,
			auxtrace_info;
	event_op3	auxtrace;
	bool		ordered_events;
	bool		ordering_requires_timestamps;
};