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

Commit 1975d36e authored by Jiri Olsa's avatar Jiri Olsa Committed by Arnaldo Carvalho de Melo
Browse files

perf stat report: Process cpu/threads maps



Adding processing of cpu/threads maps. Configuring session's evlist with
these maps.

Reported-by: default avatarKan Liang <kan.liang@intel.com>
Signed-off-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1446734469-11352-13-git-send-email-jolsa@kernel.org


[ s/stat/st/g, s/time/tm/g parameters to fix 'already defined' build error with older distros (e.g. RHEL6.7) ]
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent ba6039b6
Loading
Loading
Loading
Loading
+64 −2
Original line number Diff line number Diff line
@@ -135,6 +135,9 @@ struct perf_stat {
	struct perf_session	*session;
	u64			 bytes_written;
	struct perf_tool	 tool;
	bool			 maps_allocated;
	struct cpu_map		*cpus;
	struct thread_map	*threads;
};

static struct perf_stat		perf_stat;
@@ -234,9 +237,9 @@ static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
	return 0;
}

static int write_stat_round_event(u64 time, u64 type)
static int write_stat_round_event(u64 tm, u64 type)
{
	return perf_event__synthesize_stat_round(NULL, time, type,
	return perf_event__synthesize_stat_round(NULL, tm, type,
						 process_synthesized_event,
						 NULL);
}
@@ -1530,6 +1533,63 @@ static int __cmd_record(int argc, const char **argv)
	return argc;
}

static int set_maps(struct perf_stat *st)
{
	if (!st->cpus || !st->threads)
		return 0;

	if (WARN_ONCE(st->maps_allocated, "stats double allocation\n"))
		return -EINVAL;

	perf_evlist__set_maps(evsel_list, st->cpus, st->threads);

	if (perf_evlist__alloc_stats(evsel_list, true))
		return -ENOMEM;

	st->maps_allocated = true;
	return 0;
}

static
int process_thread_map_event(struct perf_tool *tool __maybe_unused,
			     union perf_event *event,
			     struct perf_session *session __maybe_unused)
{
	struct perf_stat *st = container_of(tool, struct perf_stat, tool);

	if (st->threads) {
		pr_warning("Extra thread map event, ignoring.\n");
		return 0;
	}

	st->threads = thread_map__new_event(&event->thread_map);
	if (!st->threads)
		return -ENOMEM;

	return set_maps(st);
}

static
int process_cpu_map_event(struct perf_tool *tool __maybe_unused,
			  union perf_event *event,
			  struct perf_session *session __maybe_unused)
{
	struct perf_stat *st = container_of(tool, struct perf_stat, tool);
	struct cpu_map *cpus;

	if (st->cpus) {
		pr_warning("Extra cpu map event, ignoring.\n");
		return 0;
	}

	cpus = cpu_map__new_data(&event->cpu_map.data);
	if (!cpus)
		return -ENOMEM;

	st->cpus = cpus;
	return set_maps(st);
}

static const char * const report_usage[] = {
	"perf stat report [<options>]",
	NULL,
@@ -1538,6 +1598,8 @@ static const char * const report_usage[] = {
static struct perf_stat perf_stat = {
	.tool = {
		.attr		= perf_event__process_attr,
		.thread_map	= process_thread_map_event,
		.cpu_map	= process_cpu_map_event,
	},
};