Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1240923 > unrolled thread

[PATCHv3 00/56] perf stat: Add scripting support

Started byJiri Olsa <jolsa@kernel.org>
First post2015-10-06 22:00 +0200
Last post2015-10-14 21:50 +0200
Articles 17 on this page of 37 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCHv3 00/56] perf stat: Add scripting support Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:00 +0200
    [PATCH 36/56] perf stat record: Synthesize attr update events Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:00 +0200
    [PATCH 08/56] perf tools: Add perf_event__fprintf_cpu_map function Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:00 +0200
    [PATCH 25/56] perf tools: Move id_offset out of struct perf_evsel union Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:00 +0200
    [PATCH 28/56] perf stat record: Add record command Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:00 +0200
    [PATCH 45/56] perf stat report: Process stat and stat round events Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:00 +0200
    [PATCH 43/56] perf stat report: Process stat config event Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:00 +0200
    [PATCH 39/56] perf tools: Add data arg to cpu_map__build_map callback Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:00 +0200
    [PATCH 13/56] perf tools: Add stat event synthesize function Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:00 +0200
    [PATCH 32/56] perf stat record: Add pipe support for record command Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 29/56] perf stat record: Initialize record features Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 19/56] perf tools: Add attr_update event unit type Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 37/56] perf tools: Add cpu_map__empty_new interface Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 50/56] perf script: Process cpu/threads maps Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 26/56] perf stat: Rename perf_stat struct into perf_stat_evsel Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 24/56] perf tools: Introduce stat feature Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 52/56] perf script: Add process_stat/process_stat_interval scripting interface Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 16/56] perf tools: Add stat round event synthesize function Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 35/56] perf stat record: Do not allow record with multiple runs mode Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 22/56] perf tools: Add perf_event__fprintf_attr_update function Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 40/56] perf stat report: Cache aggregated map entries in extra cpumap Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 42/56] perf stat report: Process cpu/threads maps Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 34/56] perf stat record: Write stat round events on record Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 21/56] perf tools: Add attr_update event name type Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 20/56] perf tools: Add attr_update event scale type Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 18/56] perf tools: Add attr_update event Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:10 +0200
    [PATCH 10/56] perf tools: Add stat config event synthesize function Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:20 +0200
    [PATCH 04/56] perf tools: Add perf_event__fprintf_thread_map function Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:20 +0200
    [PATCH 06/56] perf tools: Add cpu_map event synthesize function Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:20 +0200
    [PATCH 14/56] perf tools: Add stat event read function Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:20 +0200
    [PATCH 12/56] perf tools: Add stat event Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:20 +0200
    [PATCH 11/56] perf tools: Add stat config event read function Jiri Olsa <jolsa@kernel.org> - 2015-10-06 22:20 +0200
    RE: [PATCHv3 00/56] perf stat: Add scripting support "Liang, Kan" <kan.liang@intel.com> - 2015-10-08 20:40 +0200
      Re: [PATCHv3 00/56] perf stat: Add scripting support Jiri Olsa <jolsa@redhat.com> - 2015-10-08 22:20 +0200
        RE: [PATCHv3 00/56] perf stat: Add scripting support "Liang, Kan" <kan.liang@intel.com> - 2015-10-09 20:40 +0200
          Re: [PATCHv3 00/56] perf stat: Add scripting support Jiri Olsa <jolsa@redhat.com> - 2015-10-14 13:00 +0200
            RE: [PATCHv3 00/56] perf stat: Add scripting support "Liang, Kan" <kan.liang@intel.com> - 2015-10-14 21:50 +0200

Page 2 of 2 — ← Prev page 1 [2]


#1240946 — [PATCH 40/56] perf stat report: Cache aggregated map entries in extra cpumap

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:10 +0200
Subject[PATCH 40/56] perf stat report: Cache aggregated map entries in extra cpumap
Message-ID<qgGIH-84P-41@gated-at.bofh.it>
In reply to#1240923
Currently any time we need to access socket or core id for
given cpu, we access the sysfs topology file.

Adding cpus_aggr_map cpu_map to cache those entries.

Link: http://lkml.kernel.org/n/tip-2cw82b5piydhao8sft09am3r@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 60 +++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 56 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 9ce8ce6377ab..f38edfc1985c 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -101,6 +101,8 @@ static struct target target = {
 	.uid	= UINT_MAX,
 };
 
+typedef int (*aggr_get_id_t)(struct cpu_map *m, int cpu);
+
 static int			run_count			=  1;
 static bool			no_inherit			= false;
 static volatile pid_t		child_pid			= -1;
@@ -120,7 +122,7 @@ static unsigned int		unit_width			= 4; /* strlen("unit") */
 static bool			forever				= false;
 static struct timespec		ref_time;
 static struct cpu_map		*aggr_map;
-static int			(*aggr_get_id)(struct cpu_map *m, int cpu);
+static aggr_get_id_t		aggr_get_id;
 
 struct perf_stat {
 	bool			 record;
@@ -1150,6 +1152,7 @@ static int stat__set_big_num(const struct option *opt __maybe_unused,
 	return 0;
 }
 
+
 static int perf_stat__get_socket(struct cpu_map *map, int cpu)
 {
 	return cpu_map__get_socket(map, cpu, NULL);
@@ -1160,22 +1163,63 @@ static int perf_stat__get_core(struct cpu_map *map, int cpu)
 	return cpu_map__get_core(map, cpu, NULL);
 }
 
+static int cpu_map__get_max(struct cpu_map *map)
+{
+	int i, max = -1;
+
+	for (i = 0; i < map->nr; i++) {
+		if (map->map[i] > max)
+			max = map->map[i];
+	}
+
+	return max;
+}
+
+static struct cpu_map *cpus_aggr_map;
+
+static int perf_stat__get_aggr(aggr_get_id_t get_id, struct cpu_map *map, int idx)
+{
+	int cpu;
+
+	if (idx > map->nr)
+		return -1;
+
+	cpu = map->map[idx];
+
+	if (cpus_aggr_map->map[cpu] == -1)
+		cpus_aggr_map->map[cpu] = get_id(map, idx);
+
+	return cpus_aggr_map->map[cpu];
+}
+
+static int perf_stat__get_socket_cached(struct cpu_map *map, int idx)
+{
+	return perf_stat__get_aggr(perf_stat__get_socket, map, idx);
+}
+
+static int perf_stat__get_core_cached(struct cpu_map *map, int idx)
+{
+	return perf_stat__get_aggr(perf_stat__get_core, map, idx);
+}
+
 static int perf_stat_init_aggr_mode(void)
 {
+	int nr;
+
 	switch (stat_config.aggr_mode) {
 	case AGGR_SOCKET:
 		if (cpu_map__build_socket_map(evsel_list->cpus, &aggr_map)) {
 			perror("cannot build socket map");
 			return -1;
 		}
-		aggr_get_id = perf_stat__get_socket;
+		aggr_get_id = perf_stat__get_socket_cached;
 		break;
 	case AGGR_CORE:
 		if (cpu_map__build_core_map(evsel_list->cpus, &aggr_map)) {
 			perror("cannot build core map");
 			return -1;
 		}
-		aggr_get_id = perf_stat__get_core;
+		aggr_get_id = perf_stat__get_core_cached;
 		break;
 	case AGGR_NONE:
 	case AGGR_GLOBAL:
@@ -1184,7 +1228,15 @@ static int perf_stat_init_aggr_mode(void)
 	default:
 		break;
 	}
-	return 0;
+
+	/*
+	 * The evsel_list->cpus is the base we operate on,
+	 * taking the highest cpu number to be the size of
+	 * the aggregation translate cpumap.
+	 */
+	nr = cpu_map__get_max(evsel_list->cpus);
+	cpus_aggr_map = cpu_map__empty_new(nr + 1);
+	return cpus_aggr_map ? 0 : -ENOMEM;
 }
 
 /*
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1240948 — [PATCH 42/56] perf stat report: Process cpu/threads maps

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:10 +0200
Subject[PATCH 42/56] perf stat report: Process cpu/threads maps
Message-ID<qgGII-84P-45@gated-at.bofh.it>
In reply to#1240923
Adding processing of cpu/threads maps. Configuring session's
evlist with these maps.

Link: http://lkml.kernel.org/n/tip-f2bo5wm0cw76zc5qsjm4pztx@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 61d2abb87def..bcb9a6f85a1e 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -132,6 +132,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;
@@ -1450,6 +1453,63 @@ static int __cmd_record(int argc, const char **argv)
 	return argc;
 }
 
+static int set_maps(struct perf_stat *stat)
+{
+	if (!stat->cpus || !stat->threads)
+		return 0;
+
+	if (WARN_ONCE(stat->maps_allocated, "stats double allocation\n"))
+		return -EINVAL;
+
+	perf_evlist__set_maps(evsel_list, stat->cpus, stat->threads);
+
+	if (perf_evlist__alloc_stats(evsel_list, true))
+		return -ENOMEM;
+
+	stat->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 *stat = container_of(tool, struct perf_stat, tool);
+
+	if (stat->threads) {
+		pr_warning("Extra thread map event, ignoring.\n");
+		return 0;
+	}
+
+	stat->threads = thread_map__new_event(&event->thread_map);
+	if (!stat->threads)
+		return -ENOMEM;
+
+	return set_maps(stat);
+}
+
+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 *stat = container_of(tool, struct perf_stat, tool);
+	struct cpu_map *cpus;
+
+	if (stat->cpus) {
+		pr_warning("Extra cpu map event, ignoring.\n");
+		return 0;
+	}
+
+	cpus = cpu_map__new_event(&event->cpu_map);
+	if (!cpus)
+		return -ENOMEM;
+
+	stat->cpus = cpus;
+	return set_maps(stat);
+}
+
 static const char * const report_usage[] = {
 	"perf stat report [<options>]",
 	NULL,
@@ -1458,6 +1518,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,
 	},
 };
 
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1240949 — [PATCH 34/56] perf stat record: Write stat round events on record

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:10 +0200
Subject[PATCH 34/56] perf stat record: Write stat round events on record
Message-ID<qgGII-84P-49@gated-at.bofh.it>
In reply to#1240923
Writing stat round events on 'perf stat record' for
each interval round. In non interval mode we store
round event after the last stat event.

Link: http://lkml.kernel.org/n/tip-a43rs4c6szofeuo2gjlcpm0h@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 81ba5955b1da..f053447fde6e 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -205,6 +205,16 @@ static int process_synthesized_event(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+static int write_stat_round_event(u64 time, u64 type)
+{
+	return perf_event__synthesize_stat_round(NULL, time, type,
+						 process_synthesized_event,
+						 NULL);
+}
+
+#define WRITE_STAT_ROUND_EVENT(time, interval) \
+	write_stat_round_event(time, PERF_STAT_ROUND_TYPE__ ## interval)
+
 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
 
 static int
@@ -280,6 +290,11 @@ static void process_interval(void)
 	clock_gettime(CLOCK_MONOTONIC, &ts);
 	diff_timespec(&rs, &ts, &ref_time);
 
+	if (STAT_RECORD) {
+		if (WRITE_STAT_ROUND_EVENT(rs.tv_sec * NSECS_PER_SEC + rs.tv_nsec, INTERVAL))
+			pr_err("failed to write stat round event\n");
+	}
+
 	print_counters(&rs, 0, NULL);
 }
 
@@ -1577,6 +1592,11 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 	if (STAT_RECORD) {
 		int fd = perf_data_file__fd(&perf_stat.file);
 
+		if (!interval) {
+			if (WRITE_STAT_ROUND_EVENT(walltime_nsecs_stats.max, FINAL))
+				pr_err("failed to write stat round event\n");
+		}
+
 		if (!perf_stat.file.is_pipe) {
 			perf_stat.session->header.data_size += perf_stat.bytes_written;
 			perf_session__write_header(perf_stat.session, evsel_list, fd, true);
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1240950 — [PATCH 21/56] perf tools: Add attr_update event name type

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:10 +0200
Subject[PATCH 21/56] perf tools: Add attr_update event name type
Message-ID<qgGII-84P-51@gated-at.bofh.it>
In reply to#1240923
Adding name type attr update event, that stores/transfer
events name. Event's name is stored within perf.data's
EVENT_DESC feature, but we don't have if we get report
data from pipe.

Link: http://lkml.kernel.org/n/tip-j8b9c0ev11zisop3qup1hdy8@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/tests/attr_update.c | 24 ++++++++++++++++++++++++
 tools/perf/util/event.h        |  1 +
 tools/perf/util/header.c       | 21 +++++++++++++++++++++
 tools/perf/util/header.h       |  3 +++
 4 files changed, 49 insertions(+)

diff --git a/tools/perf/tests/attr_update.c b/tools/perf/tests/attr_update.c
index bb190d3aaefd..23ba1db9b2d4 100644
--- a/tools/perf/tests/attr_update.c
+++ b/tools/perf/tests/attr_update.c
@@ -29,10 +29,29 @@ static int process_event_scale(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+struct event_name {
+	struct perf_tool tool;
+	const char *name;
+};
+
+static int process_event_name(struct perf_tool *tool,
+			      union perf_event *event,
+			      struct perf_sample *sample __maybe_unused,
+			      struct machine *machine __maybe_unused)
+{
+	struct event_name *tmp = container_of(tool, struct event_name, tool);
+	struct attr_update_event *ev = (struct attr_update_event*) event;
+
+	TEST_ASSERT_VAL("wrong id", ev->id == 123);
+	TEST_ASSERT_VAL("wrong name", !strcmp(ev->str, tmp->name));
+	return 0;
+}
+
 int test__attr_update(void)
 {
 	struct perf_evlist *evlist;
 	struct perf_evsel *evsel;
+	struct event_name tmp;
 
 	evlist = perf_evlist__new_default();
 	TEST_ASSERT_VAL("failed to get evlist", evlist);
@@ -54,5 +73,10 @@ int test__attr_update(void)
 	TEST_ASSERT_VAL("failed to synthesize attr update scale",
 			!perf_event__synthesize_attr_update_scale(NULL, evsel, process_event_scale));
 
+	tmp.name = perf_evsel__name(evsel);
+
+	TEST_ASSERT_VAL("failed to synthesize attr update name",
+			!perf_event__synthesize_attr_update_name(&tmp.tool, evsel, process_event_name));
+
 	return 0;
 }
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index d9248975585b..88101c8fe0b1 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -286,6 +286,7 @@ struct attr_event {
 enum {
 	PERF_ATTR_UPDATE__UNIT  = 0,
 	PERF_ATTR_UPDATE__SCALE = 1,
+	PERF_ATTR_UPDATE__NAME  = 2,
 };
 
 struct attr_update_event {
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index a47ac44f6a59..2009f1fd1188 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2741,6 +2741,24 @@ perf_event__synthesize_attr_update_scale(struct perf_tool *tool,
 	return err;
 }
 
+int
+perf_event__synthesize_attr_update_name(struct perf_tool *tool,
+					struct perf_evsel *evsel,
+					perf_event__handler_t process)
+{
+	struct attr_update_event *ev;
+	size_t len = strlen(evsel->name);
+	int err;
+
+	ev = attr_update_event__alloc(len + 1, PERF_ATTR_UPDATE__NAME, evsel->id[0]);
+	if (ev == NULL)
+		return -ENOMEM;
+
+	strncpy(ev->str, evsel->name, len);
+	err = process(tool, (union perf_event*) ev, NULL, NULL);
+	free(ev);
+	return err;
+}
 
 int perf_event__synthesize_attrs(struct perf_tool *tool,
 				   struct perf_session *session,
@@ -2822,6 +2840,9 @@ int perf_event__process_attr_update(struct perf_tool *tool __maybe_unused,
 	case PERF_ATTR_UPDATE__UNIT:
 		evsel->unit = strdup(ev->str);
 		break;
+	case PERF_ATTR_UPDATE__NAME:
+		evsel->name = strdup(ev->str);
+		break;
 	case PERF_ATTR_UPDATE__SCALE:
 		evsel->scale = ev->scale;
 	default:
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 628ee46e14fd..cb538ade38d3 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -111,6 +111,9 @@ int perf_event__synthesize_attr_update_unit(struct perf_tool *tool,
 int perf_event__synthesize_attr_update_scale(struct perf_tool *tool,
 					     struct perf_evsel *evsel,
 					     perf_event__handler_t process);
+int perf_event__synthesize_attr_update_name(struct perf_tool *tool,
+					    struct perf_evsel *evsel,
+					    perf_event__handler_t process);
 int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,
 			     struct perf_evlist **pevlist);
 int perf_event__process_attr_update(struct perf_tool *tool __maybe_unused,
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1240951 — [PATCH 20/56] perf tools: Add attr_update event scale type

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:10 +0200
Subject[PATCH 20/56] perf tools: Add attr_update event scale type
Message-ID<qgGII-84P-47@gated-at.bofh.it>
In reply to#1240923
Adding scale type attr update event, that stores/transfer
events scale value. The PMU events can define the scale
value which is used to multiply events data.

Link: http://lkml.kernel.org/n/tip-by8wb1atqzhtpx86ybjhwge2@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/tests/attr_update.c | 17 +++++++++++++++++
 tools/perf/util/event.h        |  3 +++
 tools/perf/util/header.c       | 22 ++++++++++++++++++++++
 tools/perf/util/header.h       |  3 +++
 4 files changed, 45 insertions(+)

diff --git a/tools/perf/tests/attr_update.c b/tools/perf/tests/attr_update.c
index cfdb56cf3a95..bb190d3aaefd 100644
--- a/tools/perf/tests/attr_update.c
+++ b/tools/perf/tests/attr_update.c
@@ -17,6 +17,18 @@ static int process_event_unit(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+static int process_event_scale(struct perf_tool *tool __maybe_unused,
+			       union perf_event *event,
+			       struct perf_sample *sample __maybe_unused,
+			       struct machine *machine __maybe_unused)
+{
+	struct attr_update_event *ev = (struct attr_update_event*) event;
+
+	TEST_ASSERT_VAL("wrong id", ev->id == 123);
+	TEST_ASSERT_VAL("wrong scale", ev->scale = 0.123);
+	return 0;
+}
+
 int test__attr_update(void)
 {
 	struct perf_evlist *evlist;
@@ -37,5 +49,10 @@ int test__attr_update(void)
 	TEST_ASSERT_VAL("failed to synthesize attr update unit",
 			!perf_event__synthesize_attr_update_unit(NULL, evsel, process_event_unit));
 
+	evsel->scale = 0.123;
+
+	TEST_ASSERT_VAL("failed to synthesize attr update scale",
+			!perf_event__synthesize_attr_update_scale(NULL, evsel, process_event_scale));
+
 	return 0;
 }
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 501bb4a40982..d9248975585b 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -285,6 +285,7 @@ struct attr_event {
 
 enum {
 	PERF_ATTR_UPDATE__UNIT  = 0,
+	PERF_ATTR_UPDATE__SCALE = 1,
 };
 
 struct attr_update_event {
@@ -292,6 +293,8 @@ struct attr_update_event {
 	u64 type;
 	u64 id;
 
+	double scale;
+
 	/* Having 'str' for all string updates. */
 	char str[];
 };
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index a3f4bd45d880..a47ac44f6a59 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2723,6 +2723,25 @@ perf_event__synthesize_attr_update_unit(struct perf_tool *tool,
 	return err;
 }
 
+int
+perf_event__synthesize_attr_update_scale(struct perf_tool *tool,
+					 struct perf_evsel *evsel,
+					 perf_event__handler_t process)
+{
+	struct attr_update_event *ev;
+	int err;
+
+	ev = attr_update_event__alloc(0, PERF_ATTR_UPDATE__SCALE, evsel->id[0]);
+	if (ev == NULL)
+		return -ENOMEM;
+
+	ev->scale = evsel->scale;
+	err = process(tool, (union perf_event*) ev, NULL, NULL);
+	free(ev);
+	return err;
+}
+
+
 int perf_event__synthesize_attrs(struct perf_tool *tool,
 				   struct perf_session *session,
 				   perf_event__handler_t process)
@@ -2802,6 +2821,9 @@ int perf_event__process_attr_update(struct perf_tool *tool __maybe_unused,
 	switch (ev->type) {
 	case PERF_ATTR_UPDATE__UNIT:
 		evsel->unit = strdup(ev->str);
+		break;
+	case PERF_ATTR_UPDATE__SCALE:
+		evsel->scale = ev->scale;
 	default:
 		break;
 	}
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 0f00ff55f451..628ee46e14fd 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -108,6 +108,9 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,
 int perf_event__synthesize_attr_update_unit(struct perf_tool *tool,
 					    struct perf_evsel *evsel,
 					    perf_event__handler_t process);
+int perf_event__synthesize_attr_update_scale(struct perf_tool *tool,
+					     struct perf_evsel *evsel,
+					     perf_event__handler_t process);
 int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,
 			     struct perf_evlist **pevlist);
 int perf_event__process_attr_update(struct perf_tool *tool __maybe_unused,
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1240952 — [PATCH 18/56] perf tools: Add attr_update event

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:10 +0200
Subject[PATCH 18/56] perf tools: Add attr_update event
Message-ID<qgGIH-84P-33@gated-at.bofh.it>
In reply to#1240923
It'll server as base event for additional event attributes
details, that are not part of the attr event.

At the moment this event is just dummy one without specific
functionality. The type value will distinguish the update
event details. It comes in following patches.

The idea for this event is to be extensible for any update
that attr event might need in the future.

Link: http://lkml.kernel.org/n/tip-uik5iyftzgk488ttrgpjvtf6@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/event.c   |  1 +
 tools/perf/util/event.h   |  8 ++++++++
 tools/perf/util/header.c  | 20 ++++++++++++++++++++
 tools/perf/util/header.h  |  3 +++
 tools/perf/util/session.c | 21 +++++++++++++++++++++
 tools/perf/util/tool.h    |  1 +
 6 files changed, 54 insertions(+)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index f879385ec199..ffc3d524126a 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -44,6 +44,7 @@ static const char *perf_event__names[] = {
 	[PERF_RECORD_STAT_CONFIG]		= "STAT_CONFIG",
 	[PERF_RECORD_STAT]			= "STAT",
 	[PERF_RECORD_STAT_ROUND]		= "STAT_ROUND",
+	[PERF_RECORD_HEADER_ATTR_UPDATE]	= "ATTR_UPDATE",
 };
 
 const char *perf_event__name(unsigned int id)
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 04ba8ddf28f8..164ff6864ef9 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -231,6 +231,7 @@ enum perf_user_event_type { /* above any possible kernel type */
 	PERF_RECORD_STAT_CONFIG			= 75,
 	PERF_RECORD_STAT			= 76,
 	PERF_RECORD_STAT_ROUND			= 77,
+	PERF_RECORD_HEADER_ATTR_UPDATE		= 78,
 	PERF_RECORD_HEADER_MAX
 };
 
@@ -281,6 +282,12 @@ struct attr_event {
 	u64 id[];
 };
 
+struct attr_update_event {
+	struct perf_event_header header;
+	u64 type;
+	u64 id;
+};
+
 #define MAX_EVENT_NAME 64
 
 struct perf_trace_event_type {
@@ -436,6 +443,7 @@ union perf_event {
 	struct throttle_event		throttle;
 	struct sample_event		sample;
 	struct attr_event		attr;
+	struct attr_update_event	attr_update;
 	struct event_type_event		event_type;
 	struct tracing_data_event	tracing_data;
 	struct build_id_event		build_id;
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 43838003c1a1..437856eec7c4 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2745,6 +2745,26 @@ int perf_event__process_attr(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+int perf_event__process_attr_update(struct perf_tool *tool __maybe_unused,
+				    union perf_event *event,
+				    struct perf_evlist **pevlist)
+{
+	struct attr_update_event *ev = &event->attr_update;
+	struct perf_evlist *evlist;
+	struct perf_evsel *evsel;
+
+	if (!pevlist || *pevlist == NULL)
+		return -EINVAL;
+
+	evlist = *pevlist;
+
+	evsel = perf_evlist__id2evsel(evlist, ev->id);
+	if (evsel == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
 int perf_event__synthesize_tracing_data(struct perf_tool *tool, int fd,
 					struct perf_evlist *evlist,
 					perf_event__handler_t process)
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index 05f27cb6b7e3..069298367348 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -107,6 +107,9 @@ int perf_event__synthesize_attrs(struct perf_tool *tool,
 				 perf_event__handler_t process);
 int perf_event__process_attr(struct perf_tool *tool, union perf_event *event,
 			     struct perf_evlist **pevlist);
+int perf_event__process_attr_update(struct perf_tool *tool __maybe_unused,
+				    union perf_event *event,
+				    struct perf_evlist **pevlist);
 
 int perf_event__synthesize_tracing_data(struct perf_tool *tool,
 					int fd, struct perf_evlist *evlist,
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 25cee7f3af1f..47152ae58f66 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -205,6 +205,15 @@ static int process_event_synth_attr_stub(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+static int process_event_synth_attr_update_stub(struct perf_tool *tool __maybe_unused,
+						union perf_event *event __maybe_unused,
+						struct perf_evlist **pevlist
+						__maybe_unused)
+{
+	dump_printf(": unhandled!\n");
+	return 0;
+}
+
 static int process_event_sample_stub(struct perf_tool *tool __maybe_unused,
 				     union perf_event *event __maybe_unused,
 				     struct perf_sample *sample __maybe_unused,
@@ -373,6 +382,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
 		tool->unthrottle = process_event_stub;
 	if (tool->attr == NULL)
 		tool->attr = process_event_synth_attr_stub;
+	if (tool->attr_update == NULL)
+		tool->attr_update = process_event_synth_attr_update_stub;
 	if (tool->tracing_data == NULL)
 		tool->tracing_data = process_event_synth_tracing_data_stub;
 	if (tool->build_id == NULL)
@@ -624,6 +635,13 @@ static void perf_event__hdr_attr_swap(union perf_event *event,
 	mem_bswap_64(event->attr.id, size);
 }
 
+static void perf_event__hdr_attr_update_swap(union perf_event *event,
+					     bool sample_id_all __maybe_unused)
+{
+	event->attr_update.type = bswap_64(event->attr_update.type);
+	event->attr_update.id   = bswap_64(event->attr_update.id);
+}
+
 static void perf_event__event_type_swap(union perf_event *event,
 					bool sample_id_all __maybe_unused)
 {
@@ -753,6 +771,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
 	[PERF_RECORD_STAT_CONFIG]	  = perf_event__stat_config_swap,
 	[PERF_RECORD_STAT]		  = perf_event__stat_swap,
 	[PERF_RECORD_STAT_ROUND]	  = perf_event__stat_round_swap,
+	[PERF_RECORD_HEADER_ATTR_UPDATE]  = perf_event__hdr_attr_update_swap,
 	[PERF_RECORD_HEADER_MAX]	  = NULL,
 };
 
@@ -1264,6 +1283,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,
 			perf_session__set_comm_exec(session);
 		}
 		return err;
+	case PERF_RECORD_HEADER_ATTR_UPDATE:
+		return tool->attr_update(tool, event, &session->evlist);
 	case PERF_RECORD_HEADER_EVENT_TYPE:
 		/*
 		 * Depreceated, but we need to handle it for sake
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index d04d9e5f444a..59702b5d703f 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -50,6 +50,7 @@ struct perf_tool {
 			throttle,
 			unthrottle;
 	event_attr_op	attr;
+	event_attr_op	attr_update;
 	event_op2	tracing_data;
 	event_oe	finished_round;
 	event_op2	build_id,
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1240955 — [PATCH 10/56] perf tools: Add stat config event synthesize function

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:20 +0200
Subject[PATCH 10/56] perf tools: Add stat config event synthesize function
Message-ID<qgGSm-8hZ-3@gated-at.bofh.it>
In reply to#1240923
Introduce perf_event__synthesize_stat_config function to
synthesize 'struct perf_stat_config'.

Storing stat config in form of tag-value pairs in a believe
it'll sort out future version issues.

Link: http://lkml.kernel.org/n/tip-zof1adf5flwp38xdzxzn4p2z@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/tests/Build          |  1 +
 tools/perf/tests/builtin-test.c |  4 ++++
 tools/perf/tests/stat.c         | 53 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/tests/tests.h        |  1 +
 tools/perf/util/event.c         | 40 +++++++++++++++++++++++++++++++
 tools/perf/util/event.h         |  5 ++++
 6 files changed, 104 insertions(+)
 create mode 100644 tools/perf/tests/stat.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 1c0296fc95ea..ea4ef8fdd463 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -34,6 +34,7 @@ perf-y += thread-map.o
 perf-y += llvm.o
 perf-y += topology.o
 perf-y += cpumap.o
+perf-y += stat.o
 
 ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64))
 perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 3b8b518d96f9..f7a09d45408b 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -175,6 +175,10 @@ static struct test generic_tests[] = {
 		.func = test__cpu_map_synthesize,
 	},
 	{
+		.desc = "Test stat config synthesize",
+		.func = test__synthesize_stat_config,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c
new file mode 100644
index 000000000000..5e6a2441998c
--- /dev/null
+++ b/tools/perf/tests/stat.c
@@ -0,0 +1,53 @@
+#include <linux/compiler.h>
+#include "event.h"
+#include "tests.h"
+#include "stat.h"
+#include "debug.h"
+
+static bool has_term(struct stat_config_event *config,
+		     u64 tag, u64 val)
+{
+	unsigned i;
+
+	for (i = 0; i < config->nr; i++) {
+		if ((config->data[i].tag == tag) &&
+		    (config->data[i].val == val))
+			return true;
+	}
+
+	return false;
+}
+
+static int process_event(struct perf_tool *tool __maybe_unused,
+			 union perf_event *event,
+			 struct perf_sample *sample __maybe_unused,
+			 struct machine *machine __maybe_unused)
+{
+	struct stat_config_event *config = &event->stat_config;
+
+#define HAS(term, val) \
+	has_term(config, PERF_STAT_CONFIG_TERM__##term, val)
+
+	TEST_ASSERT_VAL("wrong nr",        config->nr == PERF_STAT_CONFIG_TERM__MAX);
+	TEST_ASSERT_VAL("wrong aggr_mode", HAS(AGGR_MODE, AGGR_CORE));
+	TEST_ASSERT_VAL("wrong scale",     HAS(SCALE, 1));
+	TEST_ASSERT_VAL("wrong interval",  HAS(INTERVAL, 1));
+
+#undef HAS
+
+	return 0;
+}
+
+int test__synthesize_stat_config(void)
+{
+	struct perf_stat_config stat_config = {
+		.aggr_mode	= AGGR_CORE,
+		.scale		= 1,
+		.interval	= 1,
+	};
+
+	TEST_ASSERT_VAL("failed to synthesize stat_config",
+		!perf_event__synthesize_stat_config(NULL, &stat_config, process_event, NULL));
+
+	return 0;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index c7f3c3211bcf..227ad216197e 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -69,6 +69,7 @@ int test__llvm(void);
 int test_session_topology(void);
 int test__thread_map_synthesize(void);
 int test__cpu_map_synthesize(void);
+int test__synthesize_stat_config(void);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 35a678c06b7b..9c193b99fcee 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -10,6 +10,8 @@
 #include "thread.h"
 #include "thread_map.h"
 #include "symbol/kallsyms.h"
+#include "asm/bug.h"
+#include "stat.h"
 
 static const char *perf_event__names[] = {
 	[0]					= "TOTAL",
@@ -766,6 +768,44 @@ int perf_event__synthesize_cpu_map(struct perf_tool *tool,
 	return err;
 }
 
+int perf_event__synthesize_stat_config(struct perf_tool *tool,
+				       struct perf_stat_config *config,
+				       perf_event__handler_t process,
+				       struct machine *machine)
+{
+	struct stat_config_event *event;
+	int size, i = 0, err;
+
+	size  = sizeof(*event);
+	size += (PERF_STAT_CONFIG_TERM__MAX * sizeof(event->data[0]));
+
+	event = zalloc(size);
+	if (!event)
+		return -ENOMEM;
+
+	event->header.type = PERF_RECORD_STAT_CONFIG;
+	event->header.size = size;
+	event->nr          = PERF_STAT_CONFIG_TERM__MAX;
+
+#define ADD(__term, __val)					\
+	event->data[i].tag = PERF_STAT_CONFIG_TERM__##__term;	\
+	event->data[i].val = __val;				\
+	i++;
+
+	ADD(AGGR_MODE,	config->aggr_mode)
+	ADD(INTERVAL,	config->interval)
+	ADD(SCALE,	config->scale)
+
+	WARN_ONCE(i != PERF_STAT_CONFIG_TERM__MAX,
+		  "stat config terms unbalanced\n");
+#undef ADD
+
+	err = process(tool, (union perf_event *) event, NULL, machine);
+
+	free(event);
+	return err;
+}
+
 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
 {
 	const char *s;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index ce8462255631..d4652940e086 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -426,6 +426,7 @@ void perf_event__print_totals(void);
 struct perf_tool;
 struct thread_map;
 struct cpu_map;
+struct perf_stat_config;
 
 typedef int (*perf_event__handler_t)(struct perf_tool *tool,
 				     union perf_event *event,
@@ -452,6 +453,10 @@ int perf_event__synthesize_threads(struct perf_tool *tool,
 int perf_event__synthesize_kernel_mmap(struct perf_tool *tool,
 				       perf_event__handler_t process,
 				       struct machine *machine);
+int perf_event__synthesize_stat_config(struct perf_tool *tool,
+				       struct perf_stat_config *config,
+				       perf_event__handler_t process,
+				       struct machine *machine);
 
 int perf_event__synthesize_modules(struct perf_tool *tool,
 				   perf_event__handler_t process,
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1240957 — [PATCH 04/56] perf tools: Add perf_event__fprintf_thread_map function

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:20 +0200
Subject[PATCH 04/56] perf tools: Add perf_event__fprintf_thread_map function
Message-ID<qgGSm-8hZ-15@gated-at.bofh.it>
In reply to#1240923
To display thread_map event for raw dump.

Link: http://lkml.kernel.org/n/tip-q60h5rhe4mmyvzkjst64ewhk@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/event.c | 16 ++++++++++++++++
 tools/perf/util/event.h |  1 +
 2 files changed, 17 insertions(+)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 10e852201955..ec2965b139a4 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -820,6 +820,22 @@ size_t perf_event__fprintf_mmap2(union perf_event *event, FILE *fp)
 		       event->mmap2.filename);
 }
 
+size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp)
+{
+	struct thread_map *threads = thread_map__new_event(&event->thread_map);
+	size_t ret;
+
+	ret = fprintf(fp, " nr: ");
+
+	if (threads)
+		ret += thread_map__fprintf(threads, fp);
+	else
+		ret += fprintf(fp, "failed to get threads from event\n");
+
+	thread_map__put(threads);
+	return ret;
+}
+
 int perf_event__process_mmap(struct perf_tool *tool __maybe_unused,
 			     union perf_event *event,
 			     struct perf_sample *sample,
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 3ef69fef4497..75157f3b16fb 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -516,6 +516,7 @@ size_t perf_event__fprintf_task(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf_aux(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf_itrace_start(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf_switch(union perf_event *event, FILE *fp);
+size_t perf_event__fprintf_thread_map(union perf_event *event, FILE *fp);
 size_t perf_event__fprintf(union perf_event *event, FILE *fp);
 
 u64 kallsyms__get_function_start(const char *kallsyms_filename,
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1240960 — [PATCH 06/56] perf tools: Add cpu_map event synthesize function

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:20 +0200
Subject[PATCH 06/56] perf tools: Add cpu_map event synthesize function
Message-ID<qgGSm-8hZ-17@gated-at.bofh.it>
In reply to#1240923
Introduce perf_event__synthesize_cpu_map function to
synthesize struct cpu_map.

Link: http://lkml.kernel.org/n/tip-miidn8vqsx3udu4ct8103v5f@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/tests/Build          |  1 +
 tools/perf/tests/builtin-test.c |  4 ++++
 tools/perf/tests/cpumap.c       | 29 +++++++++++++++++++++++++++++
 tools/perf/tests/tests.h        |  1 +
 tools/perf/util/event.c         | 28 ++++++++++++++++++++++++++++
 tools/perf/util/event.h         |  5 +++++
 6 files changed, 68 insertions(+)
 create mode 100644 tools/perf/tests/cpumap.c

diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 50de2253cff6..1c0296fc95ea 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -33,6 +33,7 @@ perf-y += kmod-path.o
 perf-y += thread-map.o
 perf-y += llvm.o
 perf-y += topology.o
+perf-y += cpumap.o
 
 ifeq ($(ARCH),$(filter $(ARCH),x86 arm arm64))
 perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 9bbe1c39740e..3b8b518d96f9 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -171,6 +171,10 @@ static struct test generic_tests[] = {
 		.func = test__thread_map_synthesize,
 	},
 	{
+		.desc = "Test cpu map synthesize",
+		.func = test__cpu_map_synthesize,
+	},
+	{
 		.func = NULL,
 	},
 };
diff --git a/tools/perf/tests/cpumap.c b/tools/perf/tests/cpumap.c
new file mode 100644
index 000000000000..475c040f8a8d
--- /dev/null
+++ b/tools/perf/tests/cpumap.c
@@ -0,0 +1,29 @@
+#include "tests.h"
+#include "cpumap.h"
+
+static int process_event(struct perf_tool *tool __maybe_unused,
+			 union perf_event *event,
+			 struct perf_sample *sample __maybe_unused,
+			 struct machine *machine __maybe_unused)
+{
+	struct cpu_map_event *map = &event->cpu_map;
+
+	TEST_ASSERT_VAL("wrong nr",   map->nr == 3);
+	TEST_ASSERT_VAL("wrong cpu",  map->cpu[0] == 1);
+	TEST_ASSERT_VAL("wrong cpu",  map->cpu[1] == 2);
+	TEST_ASSERT_VAL("wrong cpu",  map->cpu[2] == 4);
+	return 0;
+}
+
+int test__cpu_map_synthesize(void)
+{
+	struct cpu_map *cpus;
+
+	cpus = cpu_map__new("1,2,4");
+
+
+	TEST_ASSERT_VAL("failed to synthesize map",
+		!perf_event__synthesize_cpu_map(NULL, cpus, process_event, NULL));
+
+	return 0;
+}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 2e280a5cd579..c7f3c3211bcf 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -68,6 +68,7 @@ int test__thread_map(void);
 int test__llvm(void);
 int test_session_topology(void);
 int test__thread_map_synthesize(void);
+int test__cpu_map_synthesize(void);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index c05f4b036069..eac52f12c5c4 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -737,6 +737,34 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool,
 	return err;
 }
 
+int perf_event__synthesize_cpu_map(struct perf_tool *tool,
+				   struct cpu_map *cpus,
+				   perf_event__handler_t process,
+				   struct machine *machine)
+{
+	union perf_event *event;
+	int i, err, size;
+
+	size  = sizeof(event->cpu_map);
+	size +=	cpus->nr * sizeof(event->cpu_map.cpu[0]);
+
+	event = zalloc(size);
+	if (!event)
+		return -ENOMEM;
+
+	event->header.type = PERF_RECORD_CPU_MAP;
+	event->header.size = size;
+	event->cpu_map.nr = cpus->nr;
+
+	for (i = 0; i < cpus->nr; i++)
+		event->cpu_map.cpu[i] = cpus->map[i];
+
+	err = process(tool, event, NULL, machine);
+
+	free(event);
+	return err;
+}
+
 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
 {
 	const char *s;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 84104cfaab87..e58a36b8ecbc 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -405,6 +405,7 @@ void perf_event__print_totals(void);
 
 struct perf_tool;
 struct thread_map;
+struct cpu_map;
 
 typedef int (*perf_event__handler_t)(struct perf_tool *tool,
 				     union perf_event *event,
@@ -420,6 +421,10 @@ int perf_event__synthesize_thread_map2(struct perf_tool *tool,
 				      struct thread_map *threads,
 				      perf_event__handler_t process,
 				      struct machine *machine);
+int perf_event__synthesize_cpu_map(struct perf_tool *tool,
+				   struct cpu_map *cpus,
+				   perf_event__handler_t process,
+				   struct machine *machine);
 int perf_event__synthesize_threads(struct perf_tool *tool,
 				   perf_event__handler_t process,
 				   struct machine *machine, bool mmap_data,
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1240961 — [PATCH 14/56] perf tools: Add stat event read function

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:20 +0200
Subject[PATCH 14/56] perf tools: Add stat event read function
Message-ID<qgGSn-8hZ-25@gated-at.bofh.it>
In reply to#1240923
Introducing perf_event__process_stat_event function to process
'struct perf_stat' data from stat event.

Link: http://lkml.kernel.org/n/tip-2bvpxxp60e0qqcsecohgeju3@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/stat.c | 23 +++++++++++++++++++++++
 tools/perf/util/stat.h |  6 ++++++
 2 files changed, 29 insertions(+)

diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 2d065d065b67..0369b4516c29 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -340,3 +340,26 @@ int perf_stat_process_counter(struct perf_stat_config *config,
 
 	return 0;
 }
+
+int perf_event__process_stat_event(struct perf_tool *tool __maybe_unused,
+				   union perf_event *event,
+				   struct perf_session *session)
+{
+	struct perf_counts_values count;
+	struct stat_event *stat = &event->stat;
+	struct perf_evsel *counter;
+
+	count.val = stat->val;
+	count.ena = stat->ena;
+	count.run = stat->run;
+
+	counter = perf_evlist__id2evsel(session->evlist, stat->id);
+	if (!counter) {
+		pr_err("Failed to resolve counter for stat event.\n");
+		return -EINVAL;
+	}
+
+	*perf_counts(counter->counts, stat->cpu, stat->thread) = count;
+	counter->supported = true;
+	return 0;
+}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 62448c8175d3..a61cb0a9f23a 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -89,4 +89,10 @@ void perf_evlist__reset_stats(struct perf_evlist *evlist);
 
 int perf_stat_process_counter(struct perf_stat_config *config,
 			      struct perf_evsel *counter);
+struct perf_tool;
+union perf_event;
+struct perf_session;
+int perf_event__process_stat_event(struct perf_tool *tool,
+				   union perf_event *event,
+				   struct perf_session *session);
 #endif
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1240962 — [PATCH 12/56] perf tools: Add stat event

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:20 +0200
Subject[PATCH 12/56] perf tools: Add stat event
Message-ID<qgGSm-8hZ-19@gated-at.bofh.it>
In reply to#1240923
Adding stat event to store 'struct perf_counter_values' for
given event/cpu/thread.

Link: http://lkml.kernel.org/n/tip-56xpt7m6au4d8u39nffoqgx1@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/event.c   |  1 +
 tools/perf/util/event.h   | 19 +++++++++++++++++++
 tools/perf/util/session.c | 26 +++++++++++++++++++++++++-
 tools/perf/util/tool.h    |  3 ++-
 4 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index f60540c8987e..f7a61b0975c2 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -42,6 +42,7 @@ static const char *perf_event__names[] = {
 	[PERF_RECORD_THREAD_MAP]		= "THREAD_MAP",
 	[PERF_RECORD_CPU_MAP]			= "CPU_MAP",
 	[PERF_RECORD_STAT_CONFIG]		= "STAT_CONFIG",
+	[PERF_RECORD_STAT]			= "STAT",
 };
 
 const char *perf_event__name(unsigned int id)
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 1111b9824c69..20e28fd1eed7 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -229,6 +229,7 @@ enum perf_user_event_type { /* above any possible kernel type */
 	PERF_RECORD_THREAD_MAP			= 73,
 	PERF_RECORD_CPU_MAP			= 74,
 	PERF_RECORD_STAT_CONFIG			= 75,
+	PERF_RECORD_STAT			= 76,
 	PERF_RECORD_HEADER_MAX
 };
 
@@ -394,6 +395,23 @@ struct stat_config_event {
 	struct stat_config_term_event	data[];
 };
 
+struct stat_event {
+	struct perf_event_header	header;
+
+	u64	id;
+	u32	cpu;
+	u32	thread;
+
+	union {
+		struct {
+			u64 val;
+			u64 ena;
+			u64 run;
+		};
+		u64 values[3];
+	};
+};
+
 union perf_event {
 	struct perf_event_header	header;
 	struct mmap_event		mmap;
@@ -419,6 +437,7 @@ union perf_event {
 	struct thread_map_event		thread_map;
 	struct cpu_map_event		cpu_map;
 	struct stat_config_event	stat_config;
+	struct stat_event		stat;
 };
 
 void perf_event__print_totals(void);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 150ddc14b3fd..c5cedb8a20fb 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -296,7 +296,6 @@ int process_event_auxtrace_error_stub(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
-
 static
 int process_event_thread_map_stub(struct perf_tool *tool __maybe_unused,
 				  union perf_event *event __maybe_unused,
@@ -324,6 +323,15 @@ int process_event_stat_config_stub(struct perf_tool *tool __maybe_unused,
 	return 0;
 }
 
+static int process_stat_stub(struct perf_tool *tool __maybe_unused,
+			     union perf_event *event __maybe_unused,
+			     struct perf_session *perf_session
+			     __maybe_unused)
+{
+	dump_printf(": unhandled!\n");
+	return 0;
+}
+
 void perf_tool__fill_defaults(struct perf_tool *tool)
 {
 	if (tool->sample == NULL)
@@ -380,6 +388,8 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
 		tool->cpu_map = process_event_cpu_map_stub;
 	if (tool->stat_config == NULL)
 		tool->stat_config = process_event_stat_config_stub;
+	if (tool->stat == NULL)
+		tool->stat = process_stat_stub;
 }
 
 static void swap_sample_id_all(union perf_event *event, void *data)
@@ -682,6 +692,17 @@ static void perf_event__stat_config_swap(union perf_event *event,
 	mem_bswap_64(&event->stat_config.nr, size);
 }
 
+static void perf_event__stat_swap(union perf_event *event,
+				  bool sample_id_all __maybe_unused)
+{
+	event->stat.id     = bswap_64(event->stat.id);
+	event->stat.thread = bswap_32(event->stat.thread);
+	event->stat.cpu    = bswap_32(event->stat.cpu);
+	event->stat.val    = bswap_64(event->stat.val);
+	event->stat.ena    = bswap_64(event->stat.ena);
+	event->stat.run    = bswap_64(event->stat.run);
+}
+
 typedef void (*perf_event__swap_op)(union perf_event *event,
 				    bool sample_id_all);
 
@@ -712,6 +733,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
 	[PERF_RECORD_THREAD_MAP]	  = perf_event__thread_map_swap,
 	[PERF_RECORD_CPU_MAP]		  = perf_event__cpu_map_swap,
 	[PERF_RECORD_STAT_CONFIG]	  = perf_event__stat_config_swap,
+	[PERF_RECORD_STAT]		  = perf_event__stat_swap,
 	[PERF_RECORD_HEADER_MAX]	  = NULL,
 };
 
@@ -1254,6 +1276,8 @@ static s64 perf_session__process_user_event(struct perf_session *session,
 		return tool->cpu_map(tool, event, session);
 	case PERF_RECORD_STAT_CONFIG:
 		return tool->stat_config(tool, event, session);
+	case PERF_RECORD_STAT:
+		return tool->stat(tool, event, session);
 	default:
 		return -EINVAL;
 	}
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index aa7ae73d76b4..f0b9da0c166a 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -58,7 +58,8 @@ struct perf_tool {
 			auxtrace_error,
 			thread_map,
 			cpu_map,
-			stat_config;
+			stat_config,
+			stat;
 	event_op3	auxtrace;
 	bool		ordered_events;
 	bool		ordering_requires_timestamps;
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1240963 — [PATCH 11/56] perf tools: Add stat config event read function

FromJiri Olsa <jolsa@kernel.org>
Date2015-10-06 22:20 +0200
Subject[PATCH 11/56] perf tools: Add stat config event read function
Message-ID<qgGSn-8hZ-33@gated-at.bofh.it>
In reply to#1240923
Introducing perf_event__read_stat_config function to read
struct perf_stat_config object data from stat config event.

Link: http://lkml.kernel.org/n/tip-62ae08zz97jp2qkhygp8uet5@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/tests/stat.c |  6 ++++++
 tools/perf/util/event.c | 24 ++++++++++++++++++++++++
 tools/perf/util/event.h |  2 ++
 3 files changed, 32 insertions(+)

diff --git a/tools/perf/tests/stat.c b/tools/perf/tests/stat.c
index 5e6a2441998c..2049c5a3e4a2 100644
--- a/tools/perf/tests/stat.c
+++ b/tools/perf/tests/stat.c
@@ -24,6 +24,7 @@ static int process_event(struct perf_tool *tool __maybe_unused,
 			 struct machine *machine __maybe_unused)
 {
 	struct stat_config_event *config = &event->stat_config;
+	struct perf_stat_config stat_config;
 
 #define HAS(term, val) \
 	has_term(config, PERF_STAT_CONFIG_TERM__##term, val)
@@ -35,6 +36,11 @@ static int process_event(struct perf_tool *tool __maybe_unused,
 
 #undef HAS
 
+	perf_event__read_stat_config(&stat_config, config);
+
+	TEST_ASSERT_VAL("wrong aggr_mode", stat_config.aggr_mode == AGGR_CORE);
+	TEST_ASSERT_VAL("wrong scale",     stat_config.scale == 1);
+	TEST_ASSERT_VAL("wrong interval",  stat_config.interval == 1);
 	return 0;
 }
 
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 9c193b99fcee..f60540c8987e 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -806,6 +806,30 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool,
 	return err;
 }
 
+void perf_event__read_stat_config(struct perf_stat_config *config,
+				  struct stat_config_event *event)
+{
+	unsigned i;
+
+	for (i = 0; i < event->nr; i++) {
+
+		switch (event->data[i].tag) {
+#define CASE(__term, __val)					\
+		case PERF_STAT_CONFIG_TERM__##__term:		\
+			config->__val = event->data[i].val;	\
+			break;
+
+		CASE(AGGR_MODE, aggr_mode)
+		CASE(SCALE,     scale)
+		CASE(INTERVAL,  interval)
+#undef CASE
+		default:
+			pr_warning("unknown stat config term %" PRIu64 "\n",
+				   event->data[i].tag);
+		}
+	}
+}
+
 size_t perf_event__fprintf_comm(union perf_event *event, FILE *fp)
 {
 	const char *s;
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index d4652940e086..1111b9824c69 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -457,6 +457,8 @@ int perf_event__synthesize_stat_config(struct perf_tool *tool,
 				       struct perf_stat_config *config,
 				       perf_event__handler_t process,
 				       struct machine *machine);
+void perf_event__read_stat_config(struct perf_stat_config *config,
+				  struct stat_config_event *event);
 
 int perf_event__synthesize_modules(struct perf_tool *tool,
 				   perf_event__handler_t process,
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1242684

From"Liang, Kan" <kan.liang@intel.com>
Date2015-10-08 20:40 +0200
Message-ID<qhogH-3ew-37@gated-at.bofh.it>
In reply to#1240923
Hi Jirka

I'm doing some test with the perf/stat_script tree.
Here are the issues I found so far.

1 test case failed to build:

  CC       tests/stat.o
tests/stat.c: In function âtest__synthesize_statâ:
tests/stat.c:82:3: error: missing initializer for field âenaâ of
âstruct <anonymous>â [-Werror=missing-field-initializers]
   .ena = 200,
   ^
In file included from tests/stat.c:5:0:
/home/lk/group_read/test/perf/tools/perf/util/counts.h:10:8:
note: âenaâ declared here
    u64 ena;
        ^
tests/stat.c:83:3: error: missing initializer for field ârunâ of
âstruct <anonymous>â [-Werror=missing-field-initializers]
   .run = 300,
   ^
In file included from tests/stat.c:5:0:
/home/lk/group_read/test/perf/tools/perf/util/counts.h:11:8:
note: ârunâ declared here
    u64 run;
        ^
cc1: all warnings being treated as errors
mv: cannot stat âtests/.stat.o.tmpâ: No such file or directory
make[3]: *** [tests/stat.o] Error 1
make[2]: *** [tests] Error 2
make[1]: *** [perf-in.o] Error 2
make: *** [all] Error 2


2. it still doesn't work well with uncore event.

Here is an example:
sudo ./perf stat -e uncore_imc_1/cas_count_read/ -a --interval-print 100
--per-socket record -- sleep 1
#           time socket cpus             counts unit events
     0.100231142 S0        1               0.04 MiB  uncore_imc_1/cas_count_read/
     0.100231142 S1        1               0.08 MiB  uncore_imc_1/cas_count_read/
     0.200583556 S0        1               0.02 MiB  uncore_imc_1/cas_count_read/
     0.200583556 S1        1               0.02 MiB  uncore_imc_1/cas_count_read/

sudo ./perf stat report --per-socket
#           time socket cpus             counts unit events
     0.100231142 S0       36               0.12 MiB  uncore_imc_1/cas_count_read/
     0.100231142 S1       28      <not counted> 
MiB  uncore_imc_1/cas_count_read/
     0.200583556 S0       36               0.04 MiB  uncore_imc_1/cas_count_read/
     0.200583556 S1       28      <not counted> 
MiB  uncore_imc_1/cas_count_read/

The results are not consistent. 

I checked the perf report -D result. It looks the wrong CPU id is stored.
In my system, the uncore event should be monitored in CPU 0 and CPU 19
But it shows CPU0 and CPU1.

0x520 [0x30]: PERF_RECORD_STAT
... id 22385, cpu 0, thread 0

0x550 [0x30]: PERF_RECORD_STAT
... id 22386, cpu 1, thread 0


3. I think you have already handled new record type for perf stat record.
But the "unhandled!" message still show in the perf report -D.      

0x598 [0x30]: PERF_RECORD_STAT
... id 22385, cpu 0, thread 0
... value 1752, enabled 501473097, running 501473097
: unhandled!      <-------


4. Core dump when applying --per-core -a for stat record.

sudo ./perf stat -e 'cycles' --per-core -a record sleep 1

** Error in `./perf': corrupted double-linked list: 0x00000000036eb560 **
======= Backtrace: =========
/lib64/libc.so.6[0x3002e7bbe7]
/lib64/libc.so.6[0x3002e7d2b5]
./perf(perf_env__exit+0xfd)[0x484d1d]
./perf[0x47c45f]
./perf(main+0x610)[0x421ac0]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x3002e21b45]
./perf[0x421bd9]


5.  perf stat record may not monitor on specific CPU/whole-system.
However, perf stat report can be set to aggregate per core/socket.
If so, there is problem to show the data.
I think we need some warning here.

For example,

sudo ./perf stat -e 'cycles' record sleep 1

 Performance counter stats for 'sleep 1':

           858,928      cycles

       1.001120735 seconds time elapsed

sudo ./perf stat report -A

 Performance counter stats for '/home/lk/group_read/test/perf/
tools/perf/perf stat -e cycles record sleep 1':

CPU-1              858,928      cycles

       1.001120735 seconds time elapsed



Thanks,
Kan

> hi,
> sending another version of stat scripting.
> 
> v3 changes:
>   - added attr update event to handle unit,scale,name for event
>     it fixed the uncore_imc_1/cas_count_read/ record/report
>   - perf report -D now displays stat related events
>   - some minor and changelog fixes
> 
> v2 changes:
>   - rebased to latest Arnaldo's perf/core
>   - patches 1 to 11 already merged in
>   - added --per-core/--per-socket/-A options for perf stat report
>     command to allow custom aggregation in stat report, please
>     check new examples below
>   - couple changelogs changes
> 
> The initial attempt defined its own formula lang and allowed triggering
> user's script on the end of the stat command:
>   http://marc.info/?l=linux-kernel&m=136742146322273&w=2
> 
> This patchset abandons the idea of new formula language and rather adds
> support to:
>   - store stat data into perf.data file
>   - add python support to process stat events
> 
> Basically it allows to store stat data into perf.data and post process it with
> python scripts in a similar way we do for sampling data.
> 
> The stat data are stored in new stat, stat-round, stat-config user events.
>   stat        - stored for each read syscall of the counter
>   stat round  - stored for each interval or end of the command invocation
>   stat config - stores all the config information needed to process data
>                 so report tool could restore the same output as record
> 
> The python script can now define 'stat__<eventname>_<modifier>'
> functions to get stat events data and 'stat__interval' to get stat-round data.
> 
> See CPI script example in scripts/python/stat-cpi.py.
> 
> Also available in:
>   git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
>   perf/stat_script
> 
> thanks,
> jirka
> 
> 
> Examples:
> 
> - To record data for command stat workload:
> 
>   $ perf stat record kill
>   ...
> 
>    Performance counter stats for 'kill':
> 
>             0.372007      task-clock (msec)         #    0.613 CPUs utilized
>                    3      context-switches          #    0.008 M/sec
>                    0      cpu-migrations            #    0.000 K/sec
>                   62      page-faults               #    0.167 M/sec
>            1,129,973      cycles                    #    3.038 GHz
>      <not supported>      stalled-cycles-frontend
>      <not supported>      stalled-cycles-backend
>              813,313      instructions              #    0.72  insns per cycle
>              166,161      branches                  #  446.661 M/sec
>                8,747      branch-misses             #    5.26% of all branches
> 
>          0.000607287 seconds time elapsed
> 
> - To report perf stat data:
> 
>   $ perf stat report
> 
>    Performance counter stats for '/home/jolsa/bin/perf stat record kill':
> 
>             0.372007      task-clock (msec)         #      inf CPUs utilized
>                    3      context-switches          #    0.008 M/sec
>                    0      cpu-migrations            #    0.000 K/sec
>                   62      page-faults               #    0.167 M/sec
>            1,129,973      cycles                    #    3.038 GHz
>      <not supported>      stalled-cycles-frontend
>      <not supported>      stalled-cycles-backend
>              813,313      instructions              #    0.72  insns per cycle
>              166,161      branches                  #  446.661 M/sec
>                8,747      branch-misses             #    5.26% of all branches
> 
>          0.000000000 seconds time elapsed
> 
> - To store system-wide period stat data:
> 
>   $ perf stat -e cycles:u,instructions:u -a -I 1000 record
>   #           time             counts unit events
>        1.000265471        462,311,482      cycles:u                   (100.00%)
>        1.000265471        590,037,440      instructions:u
>        2.000483453        722,532,336      cycles:u                   (100.00%)
>        2.000483453        848,678,197      instructions:u
>        3.000759876         75,990,880      cycles:u                   (100.00%)
>        3.000759876         86,187,813      instructions:u
>   ^C     3.213960893         85,329,533      cycles:u                   (100.00%)
>        3.213960893        135,954,296      instructions:u
> 
> - To report perf stat data:
> 
>   $ perf stat report
>   #           time             counts unit events
>        1.000265471        462,311,482      cycles:u                   (100.00%)
>        1.000265471        590,037,440      instructions:u
>        2.000483453        722,532,336      cycles:u                   (100.00%)
>        2.000483453        848,678,197      instructions:u
>        3.000759876         75,990,880      cycles:u                   (100.00%)
>        3.000759876         86,187,813      instructions:u
>        3.213960893         85,329,533      cycles:u                   (100.00%)
>        3.213960893        135,954,296      instructions:u
> 
> - To run stat-cpi.py script over perf.data:
> 
>   $ perf script -s scripts/python/stat-cpi.py
>          1.000265: cpu -1, thread -1 -> cpi 0.783529 (462311482/590037440)
>          2.000483: cpu -1, thread -1 -> cpi 0.851362 (722532336/848678197)
>          3.000760: cpu -1, thread -1 -> cpi 0.881689 (75990880/86187813)
>          3.213961: cpu -1, thread -1 -> cpi 0.627634 (85329533/135954296)
> 
> - To pipe data from stat to stat-cpi script:
> 
>   $ perf stat -e cycles:u,instructions:u -A -C 0 -I 1000 record | perf script -s
> scripts/python/stat-cpi.py
>          1.000192: cpu 0, thread -1 -> cpi 0.739535 (23921908/32347236)
>          2.000376: cpu 0, thread -1 -> cpi 1.663482 (2519340/1514498)
>          3.000621: cpu 0, thread -1 -> cpi 1.396308 (16162767/11575362)
>          4.000700: cpu 0, thread -1 -> cpi 1.092246 (20077258/18381624)
>          5.000867: cpu 0, thread -1 -> cpi 0.473816 (45157586/95306156)
>          6.001034: cpu 0, thread -1 -> cpi 0.532792 (43701668/82023818)
>          7.001195: cpu 0, thread -1 -> cpi 1.122059 (29890042/26638561)
> 
> - Raw script stat data output:
> 
>   $ perf stat -e cycles:u,instructions:u -A -C 0 -I 1000 record | perf --no-
> pager script
>   CPU   THREAD             VAL             ENA             RUN            TIME EVENT
>     0       -1        12302059      1000811347      1000810712      1000198821 cycles:u
>     0       -1         2565362      1000823218      1000823218      1000198821
> instructions:u
>     0       -1        14453353      1000812704      1000812704      2000382283 cycles:u
>     0       -1         4600932      1000799342      1000799342      2000382283
> instructions:u
>     0       -1        15245106      1000774425      1000774425      3000538255 cycles:u
>     0       -1         2624324      1000769310      1000769310      3000538255
> instructions:u
> 
> - To display different aggregation in report:
> 
>   $ perf stat -e cycles -a -I 1000 record sleep 3
>   #           time             counts unit events
>        1.000223609        703,427,617      cycles
>        2.000443651        609,975,307      cycles
>        3.000569616        668,479,597      cycles
>        3.000735323          1,155,816      cycles
> 
>   $ perf stat report
>   #           time             counts unit events
>        1.000223609        703,427,617      cycles
>        2.000443651        609,975,307      cycles
>        3.000569616        668,479,597      cycles
>        3.000735323          1,155,816      cycles
> 
>   $ perf stat report --per-core
>   #           time core         cpus             counts unit events
>        1.000223609 S0-C0           2        327,612,412      cycles
>        1.000223609 S0-C1           2        375,815,205      cycles
>        2.000443651 S0-C0           2        287,462,177      cycles
>        2.000443651 S0-C1           2        322,513,130      cycles
>        3.000569616 S0-C0           2        271,571,908      cycles
>        3.000569616 S0-C1           2        396,907,689      cycles
>        3.000735323 S0-C0           2            694,977      cycles
>        3.000735323 S0-C1           2            460,839      cycles
> 
>   $ perf stat report --per-socket
>   #           time socket cpus             counts unit events
>        1.000223609 S0        4        703,427,617      cycles
>        2.000443651 S0        4        609,975,307      cycles
>        3.000569616 S0        4        668,479,597      cycles
>        3.000735323 S0        4          1,155,816      cycles
> 
>   $ perf stat report -A
>   #           time CPU                counts unit events
>        1.000223609 CPU0           205,431,505      cycles
>        1.000223609 CPU1           122,180,907      cycles
>        1.000223609 CPU2           176,649,682      cycles
>        1.000223609 CPU3           199,165,523      cycles
>        2.000443651 CPU0           148,447,922      cycles
>        2.000443651 CPU1           139,014,255      cycles
>        2.000443651 CPU2           204,436,559      cycles
>        2.000443651 CPU3           118,076,571      cycles
>        3.000569616 CPU0           149,788,954      cycles
>        3.000569616 CPU1           121,782,954      cycles
>        3.000569616 CPU2           247,277,700      cycles
>        3.000569616 CPU3           149,629,989      cycles
>        3.000735323 CPU0               269,675      cycles
>        3.000735323 CPU1               425,302      cycles
>        3.000735323 CPU2               364,169      cycles
>        3.000735323 CPU3                96,670      cycles
> 
> 
> Cc: Andi Kleen <andi@firstfloor.org>
> Cc: Ulrich Drepper <drepper@gmail.com>
> Cc: Will Deacon <will.deacon@arm.com>
> Cc: Stephane Eranian <eranian@google.com>
> Cc: Don Zickus <dzickus@redhat.com>
> ---
> Jiri Olsa (56):
>       perf tools: Add thread_map event
>       perf tools: Add thread_map event sythesize function
>       perf tools: Add thread_map__new_event function
>       perf tools: Add perf_event__fprintf_thread_map function
>       perf tools: Add cpu_map event
>       perf tools: Add cpu_map event synthesize function
>       perf tools: Add cpu_map__new_event function
>       perf tools: Add perf_event__fprintf_cpu_map function
>       perf tools: Add stat config event
>       perf tools: Add stat config event synthesize function
>       perf tools: Add stat config event read function
>       perf tools: Add stat event
>       perf tools: Add stat event synthesize function
>       perf tools: Add stat event read function
>       perf tools: Add stat round event
>       perf tools: Add stat round event synthesize function
>       perf tools: Add stat events fprintf functions
>       perf tools: Add attr_update event
>       perf tools: Add attr_update event unit type
>       perf tools: Add attr_update event scale type
>       perf tools: Add attr_update event name type
>       perf tools: Add perf_event__fprintf_attr_update function
>       perf report: Display newly added events in raw dump
>       perf tools: Introduce stat feature
>       perf tools: Move id_offset out of struct perf_evsel union
>       perf stat: Rename perf_stat struct into perf_stat_evsel
>       perf stat: Add AGGR_UNSET mode
>       perf stat record: Add record command
>       perf stat record: Initialize record features
>       perf stat record: Synthesize stat record data
>       perf stat record: Store events IDs in perf data file
>       perf stat record: Add pipe support for record command
>       perf stat record: Write stat events on record
>       perf stat record: Write stat round events on record
>       perf stat record: Do not allow record with multiple runs mode
>       perf stat record: Synthesize attr update events
>       perf tools: Add cpu_map__empty_new interface
>       perf tools: Make cpu_map__build_map global
>       perf tools: Add data arg to cpu_map__build_map callback
>       perf stat report: Cache aggregated map entries in extra cpumap
>       perf stat report: Add report command
>       perf stat report: Process cpu/threads maps
>       perf stat report: Process stat config event
>       perf stat report: Add support to initialize aggr_map from file
>       perf stat report: Process stat and stat round events
>       perf stat report: Process attr update events
>       perf stat report: Move csv_sep initialization before report command
>       perf stat report: Allow to override aggr_mode
>       perf script: Check output fields only for samples
>       perf script: Process cpu/threads maps
>       perf script: Process stat config event
>       perf script: Add process_stat/process_stat_interval scripting interface
>       perf script: Add stat default handlers
>       perf script: Display stat events by default
>       perf script: Add python support for stat events
>       perf script: Add stat-cpi.py script
> 
>  tools/perf/Documentation/perf-stat.txt             |  34 ++
>  tools/perf/builtin-record.c                        |   2 +
>  tools/perf/builtin-script.c                        | 144 ++++-
>  tools/perf/builtin-stat.c                          | 636 ++++++++++++++++++++-
>  tools/perf/scripts/python/stat-cpi.py              |  74 +++
>  tools/perf/tests/Build                             |   3 +
>  tools/perf/tests/attr_update.c                     |  82 +++
>  tools/perf/tests/builtin-test.c                    |  25 +
>  tools/perf/tests/cpumap.c                          |  39 ++
>  tools/perf/tests/stat.c                            | 111 ++++
>  tools/perf/tests/tests.h                           |   7 +
>  tools/perf/tests/thread-map.c                      |  43 ++
>  tools/perf/tests/topology.c                        |   4 +-
>  tools/perf/util/cpumap.c                           |  61 +-
>  tools/perf/util/cpumap.h                           |  11 +-
>  tools/perf/util/event.c                            | 205 +++++++
>  tools/perf/util/event.h                            | 122 +++-
>  tools/perf/util/evlist.c                           |   6 +-
>  tools/perf/util/evlist.h                           |   3 +
>  tools/perf/util/evsel.h                            |   2 +-
>  tools/perf/util/header.c                           | 146 +++++
>  tools/perf/util/header.h                           |  14 +
>  .../util/scripting-engines/trace-event-python.c    | 114 +++-
>  tools/perf/util/session.c                          | 163 ++++++
>  tools/perf/util/stat.c                             |  75 ++-
>  tools/perf/util/stat.h                             |  13 +-
>  tools/perf/util/thread_map.c                       |  27 +
>  tools/perf/util/thread_map.h                       |   3 +
>  tools/perf/util/tool.h                             |   8 +-
>  tools/perf/util/trace-event.h                      |   4 +
>  30 files changed, 2132 insertions(+), 49 deletions(-)  create mode 100644
> tools/perf/scripts/python/stat-cpi.py
>  create mode 100644 tools/perf/tests/attr_update.c  create mode 100644
> tools/perf/tests/cpumap.c  create mode 100644 tools/perf/tests/stat.c
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1242717

FromJiri Olsa <jolsa@redhat.com>
Date2015-10-08 22:20 +0200
Message-ID<qhpPr-5yd-11@gated-at.bofh.it>
In reply to#1242684
On Thu, Oct 08, 2015 at 06:37:43PM +0000, Liang, Kan wrote:
> 
> Hi Jirka
> 
> I'm doing some test with the perf/stat_script tree.
> Here are the issues I found so far.

hi,
thanks a lot for testing!

> 
> 1 test case failed to build:
> 
>   CC       tests/stat.o
> tests/stat.c: In function âtest__synthesize_statâ:
> tests/stat.c:82:3: error: missing initializer for field âenaâ of
> âstruct <anonymous>â [-Werror=missing-field-initializers]
>    .ena = 200,
>    ^
> In file included from tests/stat.c:5:0:
> /home/lk/group_read/test/perf/tools/perf/util/counts.h:10:8:
> note: âenaâ declared here
>     u64 ena;
>         ^
> tests/stat.c:83:3: error: missing initializer for field ârunâ of
> âstruct <anonymous>â [-Werror=missing-field-initializers]
>    .run = 300,
>    ^
> In file included from tests/stat.c:5:0:
> /home/lk/group_read/test/perf/tools/perf/util/counts.h:11:8:
> note: ârunâ declared here
>     u64 run;
>         ^
> cc1: all warnings being treated as errors
> mv: cannot stat âtests/.stat.o.tmpâ: No such file or directory
> make[3]: *** [tests/stat.o] Error 1
> make[2]: *** [tests] Error 2
> make[1]: *** [perf-in.o] Error 2
> make: *** [all] Error 2

saw this on another server.. have fix already

> 
> 
> 2. it still doesn't work well with uncore event.
> 
> Here is an example:
> sudo ./perf stat -e uncore_imc_1/cas_count_read/ -a --interval-print 100
> --per-socket record -- sleep 1
> #           time socket cpus             counts unit events
>      0.100231142 S0        1               0.04 MiB  uncore_imc_1/cas_count_read/
>      0.100231142 S1        1               0.08 MiB  uncore_imc_1/cas_count_read/
>      0.200583556 S0        1               0.02 MiB  uncore_imc_1/cas_count_read/
>      0.200583556 S1        1               0.02 MiB  uncore_imc_1/cas_count_read/
> 
> sudo ./perf stat report --per-socket
> #           time socket cpus             counts unit events
>      0.100231142 S0       36               0.12 MiB  uncore_imc_1/cas_count_read/
>      0.100231142 S1       28      <not counted> 
> MiB  uncore_imc_1/cas_count_read/
>      0.200583556 S0       36               0.04 MiB  uncore_imc_1/cas_count_read/
>      0.200583556 S1       28      <not counted> 
> MiB  uncore_imc_1/cas_count_read/
> 
> The results are not consistent. 
> 
> I checked the perf report -D result. It looks the wrong CPU id is stored.
> In my system, the uncore event should be monitored in CPU 0 and CPU 19
> But it shows CPU0 and CPU1.
> 
> 0x520 [0x30]: PERF_RECORD_STAT
> ... id 22385, cpu 0, thread 0
> 
> 0x550 [0x30]: PERF_RECORD_STAT
> ... id 22386, cpu 1, thread 0

it's the pmu's cpumask I did not take into account
I think we'll have to send cpumask as attr_update

> 
> 
> 3. I think you have already handled new record type for perf stat record.
> But the "unhandled!" message still show in the perf report -D.      
> 
> 0x598 [0x30]: PERF_RECORD_STAT
> ... id 22385, cpu 0, thread 0
> ... value 1752, enabled 501473097, running 501473097
> : unhandled!      <-------

yep, I was wondering about that as well.. but it's not 'handled' in perf report,
it just displays the raw output of the event.. but I think we could remove that
not to confuse

and perhaps we could also add -D for perf stat report

> 
> 
> 4. Core dump when applying --per-core -a for stat record.
> 
> sudo ./perf stat -e 'cycles' --per-core -a record sleep 1
> 
> ** Error in `./perf': corrupted double-linked list: 0x00000000036eb560 **
> ======= Backtrace: =========
> /lib64/libc.so.6[0x3002e7bbe7]
> /lib64/libc.so.6[0x3002e7d2b5]
> ./perf(perf_env__exit+0xfd)[0x484d1d]
> ./perf[0x47c45f]
> ./perf(main+0x610)[0x421ac0]
> /lib64/libc.so.6(__libc_start_main+0xf5)[0x3002e21b45]
> ./perf[0x421bd9]

could not reproduce this one.. any chance you could compile with
DEBUG=1 and re-run in gdb for more details? like which of the
frees got crazy.. ?

> 5.  perf stat record may not monitor on specific CPU/whole-system.
> However, perf stat report can be set to aggregate per core/socket.
> If so, there is problem to show the data.
> I think we need some warning here.
> 
> For example,
> 
> sudo ./perf stat -e 'cycles' record sleep 1
> 
>  Performance counter stats for 'sleep 1':
> 
>            858,928      cycles
> 
>        1.001120735 seconds time elapsed
> 
> sudo ./perf stat report -A
> 
>  Performance counter stats for '/home/lk/group_read/test/perf/
> tools/perf/perf stat -e cycles record sleep 1':
> 
> CPU-1              858,928      cycles
> 
>        1.001120735 seconds time elapsed

yep, we need to disable those options for process data 

thanks,
jirka
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1243597

From"Liang, Kan" <kan.liang@intel.com>
Date2015-10-09 20:40 +0200
Message-ID<qhKKe-1RL-23@gated-at.bofh.it>
In reply to#1242717

> 
> >
> >
> > 3. I think you have already handled new record type for perf stat record.
> > But the "unhandled!" message still show in the perf report -D.
> >
> > 0x598 [0x30]: PERF_RECORD_STAT
> > ... id 22385, cpu 0, thread 0
> > ... value 1752, enabled 501473097, running 501473097
> > : unhandled!      <-------
> 
> yep, I was wondering about that as well.. but it's not 'handled' in perf
> report, it just displays the raw output of the event.. but I think we could
> remove that not to confuse
> 
> and perhaps we could also add -D for perf stat report

Agree.

> 
> >
> >
> > 4. Core dump when applying --per-core -a for stat record.
> >
> > sudo ./perf stat -e 'cycles' --per-core -a record sleep 1
> >
> > ** Error in `./perf': corrupted double-linked list: 0x00000000036eb560
> > ** ======= Backtrace: ========= /lib64/libc.so.6[0x3002e7bbe7]
> > /lib64/libc.so.6[0x3002e7d2b5] ./perf(perf_env__exit+0xfd)[0x484d1d]
> > ./perf[0x47c45f]
> > ./perf(main+0x610)[0x421ac0]
> > /lib64/libc.so.6(__libc_start_main+0xf5)[0x3002e21b45]
> > ./perf[0x421bd9]
> 
> could not reproduce this one.. any chance you could compile with
> DEBUG=1 and re-run in gdb for more details? like which of the frees got
> crazy.. ?
>
The crash is not caused by this patch set. It's also a bug in current perf.
I've submitted a patch for that.
https://lkml.org/lkml/2015/10/9/575

Thanks,
Kan


 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1246516

FromJiri Olsa <jolsa@redhat.com>
Date2015-10-14 13:00 +0200
Message-ID<qjrWO-4AF-15@gated-at.bofh.it>
In reply to#1243597
On Fri, Oct 09, 2015 at 06:31:23PM +0000, Liang, Kan wrote:

SNIP

> > could not reproduce this one.. any chance you could compile with
> > DEBUG=1 and re-run in gdb for more details? like which of the frees got
> > crazy.. ?
> >
> The crash is not caused by this patch set. It's also a bug in current perf.
> I've submitted a patch for that.
> https://lkml.org/lkml/2015/10/9/575
> 
> Thanks,
> Kan

I pushed fixed code into my perf/stat_script branch, could you please test?

thanks,
jirka
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1247113

From"Liang, Kan" <kan.liang@intel.com>
Date2015-10-14 21:50 +0200
Message-ID<qjAdH-8se-1@gated-at.bofh.it>
In reply to#1246516

> 
> On Fri, Oct 09, 2015 at 06:31:23PM +0000, Liang, Kan wrote:
> 
> SNIP
> 
> > > could not reproduce this one.. any chance you could compile with
> > > DEBUG=1 and re-run in gdb for more details? like which of the frees
> > > got crazy.. ?
> > >
> > The crash is not caused by this patch set. It's also a bug in current perf.
> > I've submitted a patch for that.
> > https://lkml.org/lkml/2015/10/9/575
> >
> > Thanks,
> > Kan
> 
> I pushed fixed code into my perf/stat_script branch, could you please test?
> 

The new fixed code works well. I don't find any issues so far.

Kan
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | linux.kernel


csiph-web