Skip to contentSkip to conversation

perf stat: Introduce --per-thread option

PATCH In review Jiri Olsa 3 participants 47 messages Jun 26, 2015 – Jun 30, 2015 perf events

lore
Share & tools
lore

Jiri Olsa

author reviewer
#0 lore raw

v5 cover perf stat: Introduce --per-thread option

hi,
adding the possibility to display stat data per thread.

Allowing following commands and output:

  $ perf stat  -e cycles,instructions --per-thread -p 30190,30242
  ^C
   Performance counter stats for process id '30190,30242':
               cat-30190                     0      cycles
               yes-30242         3,842,525,421      cycles
               cat-30190                     0      instructions
               yes-30242        10,370,817,010      instructions
         1.143155657 seconds time elapsed

Also works under interval mode:

  $ perf stat  -e cycles,instructions --per-thread -p 30190,30242 -I 1000
  #           time             comm-pid                  counts unit events
       1.000073435              cat-30190                89,058      cycles
       1.000073435              yes-30242         3,360,786,902      cycles                     (100.00%)
       1.000073435              cat-30190                14,066      instructions
       1.000073435              yes-30242         9,069,937,462      instructions
       2.000204830              cat-30190                     0      cycles
       2.000204830              yes-30242         3,351,667,626      cycles
       2.000204830              cat-30190                     0      instructions
       2.000204830              yes-30242         9,045,796,885      instructions
  ^C     2.771286639              cat-30190                     0      cycles
       2.771286639              yes-30242         2,593,884,166      cycles
       2.771286639              cat-30190                     0      instructions
       2.771286639              yes-30242         7,001,171,191      instructions

Available in here:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/per_thread

v5 changes:
- reading comms explicitly by thread_map__read_comms, so it gets read only within 'perf stat --per-thread'
- introducing thread_map__reset function
- several patches got accepted, rebased on latest perf/core

v4 changes:
- add thread_map__set_(pid|comm) interface
- several fixes for task comm string reading
- added perf_evlist__reset_stats function

v3 changes:
- some patches already pulled in, rebased on latest acme's perf/core
- fixed cpu_map__get/thread_map__get to accept NULL map
- renamed propagate_maps to perf_evlist__propagate_maps
- renamed --per-task option to --per-thread
- changed 'task-pid' header output to 'comm-pid'

v2 changes:
- renamed xyarray__zero to xyarray__reset
- using atomic_t for cpu_map/thread_map refcnt
- moving all stat functions into stat object
- using init_stats to initialize 'struct stats*'
- change TASK-$pid output into $comm-$pid
- updated doc with --per-task option

thanks,
jirka
---
Jiri Olsa (22):
perf thread_map: Introduce thread_map__reset function
perf tools: Add comm string into struct thread_map
perf tests: Add thread_map object tests
perf stat: Introduce perf_counts function
perf stat: Use xyarray for cpu evsel counts
perf stat: Make stats work over the thread dimension
perf stat: Rename struct perf_counts::cpu member to values perf stat: Introduce perf_evlist__reset_stats
perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into stat object perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts into stat object perf stat: Move perf_evlist__(alloc|free|reset)_stats into stat object perf stat: Introduce perf_evsel__alloc_stats function
perf stat: Introduce perf_evsel__read function
perf stat: Introduce read_counters function
perf stat: Separate counters reading and processing
perf stat: Move zero_per_pkg into counter process code
perf stat: Move perf_stat initialization counter process code perf stat: Remove perf_evsel__read_cb function
perf stat: Rename print_interval to process_interval
perf stat: Using init_stats instead of memset
perf stat: Introduce print_counters function
perf stat: Introduce --per-thread option

 tools/perf/Documentation/perf-stat.txt     |   4 +
 tools/perf/builtin-stat.c                  | 402 +++++++++++++++++++++++++++++++------------------------------
 tools/perf/tests/Build                     |   1 +
 tools/perf/tests/builtin-test.c            |   4 +
 tools/perf/tests/openat-syscall-all-cpus.c |   6 +-
 tools/perf/tests/openat-syscall.c          |   4 +-
 tools/perf/tests/tests.h                   |   1 +
 tools/perf/tests/thread-map.c              |  38 ++++++
 tools/perf/util/evlist.h                   |   1 -
 tools/perf/util/evsel.c                    |  24 ++--
 tools/perf/util/evsel.h                    |  28 +----
 tools/perf/util/python-ext-sources         |   1 +
 tools/perf/util/stat.c                     | 132 ++++++++++++++++++--
 tools/perf/util/stat.h                     |  47 +++++++-
 tools/perf/util/thread_map.c               |  76 +++++++++++-
 tools/perf/util/thread_map.h               |   8 ++
 16 files changed, 523 insertions(+), 254 deletions(-)
 create mode 100644 tools/perf/tests/thread-map.c
author reviewer
#1 lore raw

PATCH v5 1/22 perf thread_map: Introduce thread_map__reset function

We need to reset newly allocated 'struct thread_map_data' entries, because we will introduce new comm memeber, which will get set later or not at all.

---
 tools/perf/util/thread_map.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
tools/perf/util/thread_map.c +16 -1
index 368cc58c6892..562e5e2c571c 100644
@@ -21,11 +21,26 @@ static int filter(const struct dirent *dir)
 		return 1;
 }
 
+static void thread_map__reset(struct thread_map *map, int start, int nr)
+{
+	size_t size = (nr - start) * sizeof(struct thread_map_data);
+
+	memset(&map->map[start], 0, size);
+}
+
 static struct thread_map *thread_map__realloc(struct thread_map *map, int nr)
 {
 	size_t size = sizeof(*map) + sizeof(map->map[0]) * nr;
+	int start = map ? map->nr : 0;
 
-	return realloc(map, size);
+	map = realloc(map, size);
+	/*
+	 * We only realloc to add more items, let's reset new items.
+	 */
+	if (map)
+		thread_map__reset(map, start, nr);
+
+	return map;
 }
 
 #define thread_map__alloc(__nr) thread_map__realloc(NULL, __nr)
Signature · 1 line
1.9.3
#2 lore raw

Re: [PATCH 01/22] perf thread_map: Introduce thread_map__reset function

Em Fri, Jun 26, 2015 at 11:29:06AM +0200, Jiri Olsa escreveu:

Quoted 3 lines

We need to reset newly allocated 'struct thread_map_data' entries, because we will introduce new comm memeber, which will get set later or not at all.

And this is an array that never shrinks, right?

At least current usage just makes it grow, ok.

- Arnaldo

Quoted 40 lines
---
 tools/perf/util/thread_map.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
tools/perf/util/thread_map.c +16 -1
index 368cc58c6892..562e5e2c571c 100644
@@ -21,11 +21,26 @@ static int filter(const struct dirent *dir)
 		return 1;
 }
 
+static void thread_map__reset(struct thread_map *map, int start, int nr)
+{
+	size_t size = (nr - start) * sizeof(struct thread_map_data);
+
+	memset(&map->map[start], 0, size);
+}
+
 static struct thread_map *thread_map__realloc(struct thread_map *map, int nr)
 {
 	size_t size = sizeof(*map) + sizeof(map->map[0]) * nr;
+	int start = map ? map->nr : 0;
 
-	return realloc(map, size);
+	map = realloc(map, size);
+	/*
+	 * We only realloc to add more items, let's reset new items.
+	 */
+	if (map)
+		thread_map__reset(map, start, nr);
+
+	return map;
 }
 
 #define thread_map__alloc(__nr) thread_map__realloc(NULL, __nr)
Signature · 1 line
1.9.3
#3 lore raw

[tip:perf/urgent] perf thread_map: Introduce thread_map__reset function

In reply to Jiri Olsa
perf thread_map: Introduce thread_map__reset function
Commit-ID:  62eea464380633b88902da35bf9cbd8515289703
Gitweb:     http://git.kernel.org/tip/62eea464380633b88902da35bf9cbd8515289703
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:06 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:03:41 -0300

perf thread_map: Introduce thread_map__reset function

We need to reset newly allocated 'struct thread_map_data' entries, because we will introduce new comm memeber, which will get set later or not at all.

Cc Adrian Hunter <[email protected]>
Cc Andi Kleen <[email protected]>
Cc David Ahern <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
[ Use sizeof(map->map[0]) to be independent of the array entry type ]
---
 tools/perf/util/thread_map.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)
tools/perf/util/thread_map.c +16 -1
index 368cc58..ed76c17 100644
@@ -21,11 +21,26 @@ static int filter(const struct dirent *dir)
 		return 1;
 }
 
+static void thread_map__reset(struct thread_map *map, int start, int nr)
+{
+	size_t size = (nr - start) * sizeof(map->map[0]);
+
+	memset(&map->map[start], 0, size);
+}
+
 static struct thread_map *thread_map__realloc(struct thread_map *map, int nr)
 {
 	size_t size = sizeof(*map) + sizeof(map->map[0]) * nr;
+	int start = map ? map->nr : 0;
 
-	return realloc(map, size);
+	map = realloc(map, size);
+	/*
+	 * We only realloc to add more items, let's reset new items.
+	 */
+	if (map)
+		thread_map__reset(map, start, nr);
+
+	return map;
 }
 
 #define thread_map__alloc(__nr) thread_map__realloc(NULL, __nr)
author reviewer
#4 lore raw

PATCH v5 2/22 perf tools: Add comm string into struct thread_map

In reply to Jiri Olsa

Adding support to hold comm name together with pids in 'struct thread_map'. It will be useful for --per-thread option to display task pid together with task name.

Adding thread_map__read_comms function that reads/set comm string for the 'struct thread_map'.

Getting the task name from /proc/$pid/comm.

---
 tools/perf/util/python-ext-sources |  1 +
 tools/perf/util/thread_map.c       | 59 ++++++++++++++++++++++++++++++++++++++
 tools/perf/util/thread_map.h       |  8 ++++++
 3 files changed, 68 insertions(+)
tools/perf/util/python-ext-sources +1 -0
index 5925fec90562..e23ded40c79e 100644
@@ -20,3 +20,4 @@ util/stat.c
 util/strlist.c
 util/trace-event.c
 ../../lib/rbtree.c
+util/string.c
tools/perf/util/thread_map.c +59 -0

79 lines not on this page · raw message

tools/perf/util/thread_map.h +8 -0
index 6b0cd2dc006b..af679d8a50f8 100644
@@ -7,6 +7,7 @@
 
 struct thread_map_data {
 	pid_t    pid;
+	char	*comm;
 };
 
 struct thread_map {
@@ -44,4 +45,11 @@ thread_map__set_pid(struct thread_map *map, int thread, pid_t pid)
 {
 	map->map[thread].pid = pid;
 }
+
+static inline char *thread_map__comm(struct thread_map *map, int thread)
+{
+	return map->map[thread].comm;
+}
+
+void thread_map__read_comms(struct thread_map *threads);
 #endif	/* __PERF_THREAD_MAP_H */
Signature · 1 line
1.9.3
#5 lore raw

[tip:perf/urgent] perf thrad_map: Add comm string into array

perf thrad_map: Add comm string into array
Commit-ID:  792402fd5c0a5a5300868e9dfc8ee569f3a39169
Gitweb:     http://git.kernel.org/tip/792402fd5c0a5a5300868e9dfc8ee569f3a39169
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:07 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:07:01 -0300

perf thrad_map: Add comm string into array

Adding support to hold comm name together with pids in 'struct thread_map'. It will be useful for --per-thread option to display task pid together with task name.

Adding thread_map__read_comms function that reads/set comm string for the 'struct thread_map'.

Getting the task name from /proc/$pid/comm.

---
 tools/perf/util/python-ext-sources |  1 +
 tools/perf/util/thread_map.c       | 59 ++++++++++++++++++++++++++++++++++++++
 tools/perf/util/thread_map.h       |  8 ++++++
 3 files changed, 68 insertions(+)
tools/perf/util/python-ext-sources +1 -0
index 5925fec..e23ded4 100644
@@ -20,3 +20,4 @@ util/stat.c
 util/strlist.c
 util/trace-event.c
 ../../lib/rbtree.c
+util/string.c
tools/perf/util/thread_map.c +59 -0

79 lines not on this page · raw message

tools/perf/util/thread_map.h +8 -0
index 6b0cd2d..af679d8 100644
@@ -7,6 +7,7 @@
 
 struct thread_map_data {
 	pid_t    pid;
+	char	*comm;
 };
 
 struct thread_map {
@@ -44,4 +45,11 @@ thread_map__set_pid(struct thread_map *map, int thread, pid_t pid)
 {
 	map->map[thread].pid = pid;
 }
+
+static inline char *thread_map__comm(struct thread_map *map, int thread)
+{
+	return map->map[thread].comm;
+}
+
+void thread_map__read_comms(struct thread_map *threads);
 #endif	/* __PERF_THREAD_MAP_H */
author reviewer
#6 lore raw

PATCH v5 3/22 perf tests: Add thread_map object tests

In reply to Jiri Olsa

Adding thread_map object tests for comm name values.

---
 tools/perf/tests/Build          |  1 +
 tools/perf/tests/builtin-test.c |  4 ++++
 tools/perf/tests/tests.h        |  1 +
 tools/perf/tests/thread-map.c   | 38 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 44 insertions(+)
 create mode 100644 tools/perf/tests/thread-map.c
tools/perf/tests/Build +1 -0
index ee41e705b2eb..d20d6e6ab65b 100644
@@ -31,6 +31,7 @@ perf-y += code-reading.o
 perf-y += sample-parsing.o
 perf-y += parse-no-sample-id-all.o
 perf-y += kmod-path.o
+perf-y += thread-map.o
 
 perf-$(CONFIG_X86) += perf-time-to-tsc.o
 
tools/perf/tests/builtin-test.c +4 -0
index 87b9961646e4..c1dde733c3a6 100644
@@ -171,6 +171,10 @@ static struct test {
 		.func = test__kmod_path__parse,
 	},
 	{
+		.desc = "Test thread map",
+		.func = test__thread_map,
+	},
+	{
 		.func = NULL,
 	},
 };
tools/perf/tests/tests.h +1 -0
index 8e5038b48ba8..ebb47d96bc0b 100644
@@ -61,6 +61,7 @@ int test__switch_tracking(void);
 int test__fdarray__filter(void);
 int test__fdarray__add(void);
 int test__kmod_path__parse(void);
+int test__thread_map(void);
 
 #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/tests/thread-map.c new file +38 -0
new file mode 100644
index 000000000000..5acf000939ea
@@ -0,0 +1,38 @@
+#include <sys/types.h>
+#include <unistd.h>
+#include "tests.h"
+#include "thread_map.h"
+#include "debug.h"
+
+int test__thread_map(void)
+{
+	struct thread_map *map;
+
+	/* test map on current pid */
+	map = thread_map__new_by_pid(getpid());
+	TEST_ASSERT_VAL("failed to alloc map", map);
+
+	thread_map__read_comms(map);
+
+	TEST_ASSERT_VAL("wrong nr", map->nr == 1);
+	TEST_ASSERT_VAL("wrong pid",
+			thread_map__pid(map, 0) == getpid());
+	TEST_ASSERT_VAL("wrong comm",
+			thread_map__comm(map, 0) &&
+			!strcmp(thread_map__comm(map, 0), "perf"));
+	thread_map__put(map);
+
+	/* test dummy pid */
+	map = thread_map__new_dummy();
+	TEST_ASSERT_VAL("failed to alloc map", map);
+
+	thread_map__read_comms(map);
+
+	TEST_ASSERT_VAL("wrong nr", map->nr == 1);
+	TEST_ASSERT_VAL("wrong pid", thread_map__pid(map, 0) == -1);
+	TEST_ASSERT_VAL("wrong comm",
+			thread_map__comm(map, 0) &&
+			!strcmp(thread_map__comm(map, 0), "dummy"));
+	thread_map__put(map);
+	return 0;
+}
Signature · 1 line
1.9.3
#7 lore raw

[tip:perf/urgent] perf tests: Add thread_map object tests

perf tests: Add thread_map object tests
Commit-ID:  134aa44f6bff6b967efb85255ee9e8982cb8e486
Gitweb:     http://git.kernel.org/tip/134aa44f6bff6b967efb85255ee9e8982cb8e486
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:08 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:09:38 -0300

perf tests: Add thread_map object tests

Adding thread_map object tests for comm name values.

---
 tools/perf/tests/Build          |  1 +
 tools/perf/tests/builtin-test.c |  4 ++++
 tools/perf/tests/tests.h        |  1 +
 tools/perf/tests/thread-map.c   | 38 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 44 insertions(+)
tools/perf/tests/Build +1 -0
index ee41e70..d20d6e6 100644
@@ -31,6 +31,7 @@ perf-y += code-reading.o
 perf-y += sample-parsing.o
 perf-y += parse-no-sample-id-all.o
 perf-y += kmod-path.o
+perf-y += thread-map.o
 
 perf-$(CONFIG_X86) += perf-time-to-tsc.o
 
tools/perf/tests/builtin-test.c +4 -0
index 87b9961..c1dde73 100644
@@ -171,6 +171,10 @@ static struct test {
 		.func = test__kmod_path__parse,
 	},
 	{
+		.desc = "Test thread map",
+		.func = test__thread_map,
+	},
+	{
 		.func = NULL,
 	},
 };
tools/perf/tests/tests.h +1 -0
index 8e5038b..ebb47d9 100644
@@ -61,6 +61,7 @@ int test__switch_tracking(void);
 int test__fdarray__filter(void);
 int test__fdarray__add(void);
 int test__kmod_path__parse(void);
+int test__thread_map(void);
 
 #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/tests/thread-map.c new file +38 -0
new file mode 100644
index 0000000..5acf000
@@ -0,0 +1,38 @@
+#include <sys/types.h>
+#include <unistd.h>
+#include "tests.h"
+#include "thread_map.h"
+#include "debug.h"
+
+int test__thread_map(void)
+{
+	struct thread_map *map;
+
+	/* test map on current pid */
+	map = thread_map__new_by_pid(getpid());
+	TEST_ASSERT_VAL("failed to alloc map", map);
+
+	thread_map__read_comms(map);
+
+	TEST_ASSERT_VAL("wrong nr", map->nr == 1);
+	TEST_ASSERT_VAL("wrong pid",
+			thread_map__pid(map, 0) == getpid());
+	TEST_ASSERT_VAL("wrong comm",
+			thread_map__comm(map, 0) &&
+			!strcmp(thread_map__comm(map, 0), "perf"));
+	thread_map__put(map);
+
+	/* test dummy pid */
+	map = thread_map__new_dummy();
+	TEST_ASSERT_VAL("failed to alloc map", map);
+
+	thread_map__read_comms(map);
+
+	TEST_ASSERT_VAL("wrong nr", map->nr == 1);
+	TEST_ASSERT_VAL("wrong pid", thread_map__pid(map, 0) == -1);
+	TEST_ASSERT_VAL("wrong comm",
+			thread_map__comm(map, 0) &&
+			!strcmp(thread_map__comm(map, 0), "dummy"));
+	thread_map__put(map);
+	return 0;
+}
author reviewer
#8 lore raw

PATCH v5 4/22 perf stat: Introduce perf_counts function

In reply to Jiri Olsa

Introducing perf_counts function, that returns 'struct perf_counts_values' pointer for given cpu.

Also moving perf_counts* structures into stat.h.

---
 tools/perf/builtin-stat.c                  | 14 +++++++-------
 tools/perf/tests/openat-syscall-all-cpus.c |  4 ++--
 tools/perf/tests/openat-syscall.c          |  2 +-
 tools/perf/util/evsel.c                    |  6 +++---
 tools/perf/util/evsel.h                    | 18 +-----------------
 tools/perf/util/stat.h                     | 23 +++++++++++++++++++++++
 6 files changed, 37 insertions(+), 30 deletions(-)
tools/perf/builtin-stat.c +7 -7
index 3e1636cae76b..49b90374232c 100644
@@ -316,7 +316,7 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
 		if (!evsel->snapshot)
 			perf_evsel__compute_deltas(evsel, cpu, count);
 		perf_counts_values__scale(count, scale, NULL);
-		evsel->counts->cpu[cpu] = *count;
+		*perf_counts(evsel->counts, cpu) = *count;
 		if (aggr_mode == AGGR_NONE)
 			perf_stat__update_shadow_stats(evsel, count->values, cpu);
 		break;
@@ -805,9 +805,9 @@ static void print_aggr(char *prefix)
 				s2 = aggr_get_id(evsel_list->cpus, cpu2);
 				if (s2 != id)
 					continue;
-				val += counter->counts->cpu[cpu].val;
-				ena += counter->counts->cpu[cpu].ena;
-				run += counter->counts->cpu[cpu].run;
+				val += perf_counts(counter->counts, cpu)->val;
+				ena += perf_counts(counter->counts, cpu)->ena;
+				run += perf_counts(counter->counts, cpu)->run;
 				nr++;
 			}
 			if (prefix)
@@ -915,9 +915,9 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
 	int cpu;
 
 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
-		val = counter->counts->cpu[cpu].val;
-		ena = counter->counts->cpu[cpu].ena;
-		run = counter->counts->cpu[cpu].run;
+		val = perf_counts(counter->counts, cpu)->val;
+		ena = perf_counts(counter->counts, cpu)->ena;
+		run = perf_counts(counter->counts, cpu)->run;
 
 		if (prefix)
 			fprintf(output, "%s", prefix);
tools/perf/tests/openat-syscall-all-cpus.c +2 -2
index b8d552b13950..e8d944fe1bd0 100644
@@ -98,9 +98,9 @@ int test__openat_syscall_event_on_all_cpus(void)
 		}
 
 		expected = nr_openat_calls + cpu;
-		if (evsel->counts->cpu[cpu].val != expected) {
+		if (perf_counts(evsel->counts, cpu)->val != expected) {
 			pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
-				 expected, cpus->map[cpu], evsel->counts->cpu[cpu].val);
+				 expected, cpus->map[cpu], perf_counts(evsel->counts, cpu)->val);
 			err = -1;
 		}
 	}
tools/perf/tests/openat-syscall.c +1 -1
index bdfa1f446681..e86fc477a74f 100644
@@ -44,7 +44,7 @@ int test__openat_syscall_event(void)
 		goto out_close_fd;
 	}
 
-	if (evsel->counts->cpu[0].val != nr_openat_calls) {
+	if (perf_counts(evsel->counts, 0)->val != nr_openat_calls) {
 		pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
 			 nr_openat_calls, evsel->counts->cpu[0].val);
 		goto out_close_fd;
tools/perf/util/evsel.c +3 -3
index 1b2f480a3e82..8401b042b9d4 100644
@@ -910,8 +910,8 @@ void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
 		tmp = evsel->prev_raw_counts->aggr;
 		evsel->prev_raw_counts->aggr = *count;
 	} else {
-		tmp = evsel->prev_raw_counts->cpu[cpu];
-		evsel->prev_raw_counts->cpu[cpu] = *count;
+		tmp = *perf_counts(evsel->prev_raw_counts, cpu);
+		*perf_counts(evsel->prev_raw_counts, cpu) = *count;
 	}
 
 	count->val = count->val - tmp.val;
@@ -972,7 +972,7 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
 
 	perf_evsel__compute_deltas(evsel, cpu, &count);
 	perf_counts_values__scale(&count, scale, NULL);
-	evsel->counts->cpu[cpu] = count;
+	*perf_counts(evsel->counts, cpu) = count;
 	return 0;
 }
 
tools/perf/util/evsel.h +1 -17
index 4dbf32d94dfb..b420f8f5fc5d 100644
@@ -9,23 +9,7 @@
 #include "xyarray.h"
 #include "symbol.h"
 #include "cpumap.h"
-
-struct perf_counts_values {
-	union {
-		struct {
-			u64 val;
-			u64 ena;
-			u64 run;
-		};
-		u64 values[3];
-	};
-};
-
-struct perf_counts {
-	s8		   	  scaled;
-	struct perf_counts_values aggr;
-	struct perf_counts_values cpu[];
-};
+#include "stat.h"
 
 struct perf_evsel;
 
tools/perf/util/stat.h +23 -0
index 093dc3cb28dd..5e43348836a6 100644
@@ -31,6 +31,29 @@ enum aggr_mode {
 	AGGR_CORE,
 };
 
+struct perf_counts_values {
+	union {
+		struct {
+			u64 val;
+			u64 ena;
+			u64 run;
+		};
+		u64 values[3];
+	};
+};
+
+struct perf_counts {
+	s8			  scaled;
+	struct perf_counts_values aggr;
+	struct perf_counts_values cpu[];
+};
+
+static inline struct perf_counts_values*
+perf_counts(struct perf_counts *counts, int cpu)
+{
+	return &counts->cpu[cpu];
+}
+
 void update_stats(struct stats *stats, u64 val);
 double avg_stats(struct stats *stats);
 double stddev_stats(struct stats *stats);
Signature · 1 line
1.9.3
#9 lore raw

[tip:perf/urgent] perf stat: Introduce perf_counts function

perf stat: Introduce perf_counts function
Commit-ID:  1ac77e1ce8654ec94ada0c508d58ba80a4647fba
Gitweb:     http://git.kernel.org/tip/1ac77e1ce8654ec94ada0c508d58ba80a4647fba
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:09 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:11:26 -0300

perf stat: Introduce perf_counts function

Introducing perf_counts function, that returns 'struct perf_counts_values' pointer for given cpu.

Also moving perf_counts* structures into stat.h.

---
 tools/perf/builtin-stat.c                  | 14 +++++++-------
 tools/perf/tests/openat-syscall-all-cpus.c |  4 ++--
 tools/perf/tests/openat-syscall.c          |  2 +-
 tools/perf/util/evsel.c                    |  6 +++---
 tools/perf/util/evsel.h                    | 18 +-----------------
 tools/perf/util/stat.h                     | 23 +++++++++++++++++++++++
 6 files changed, 37 insertions(+), 30 deletions(-)
tools/perf/builtin-stat.c +7 -7
index 3e1636c..49b9037 100644
@@ -316,7 +316,7 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
 		if (!evsel->snapshot)
 			perf_evsel__compute_deltas(evsel, cpu, count);
 		perf_counts_values__scale(count, scale, NULL);
-		evsel->counts->cpu[cpu] = *count;
+		*perf_counts(evsel->counts, cpu) = *count;
 		if (aggr_mode == AGGR_NONE)
 			perf_stat__update_shadow_stats(evsel, count->values, cpu);
 		break;
@@ -805,9 +805,9 @@ static void print_aggr(char *prefix)
 				s2 = aggr_get_id(evsel_list->cpus, cpu2);
 				if (s2 != id)
 					continue;
-				val += counter->counts->cpu[cpu].val;
-				ena += counter->counts->cpu[cpu].ena;
-				run += counter->counts->cpu[cpu].run;
+				val += perf_counts(counter->counts, cpu)->val;
+				ena += perf_counts(counter->counts, cpu)->ena;
+				run += perf_counts(counter->counts, cpu)->run;
 				nr++;
 			}
 			if (prefix)
@@ -915,9 +915,9 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
 	int cpu;
 
 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
-		val = counter->counts->cpu[cpu].val;
-		ena = counter->counts->cpu[cpu].ena;
-		run = counter->counts->cpu[cpu].run;
+		val = perf_counts(counter->counts, cpu)->val;
+		ena = perf_counts(counter->counts, cpu)->ena;
+		run = perf_counts(counter->counts, cpu)->run;
 
 		if (prefix)
 			fprintf(output, "%s", prefix);
tools/perf/tests/openat-syscall-all-cpus.c +2 -2
index b8d552b..e8d944f 100644
@@ -98,9 +98,9 @@ int test__openat_syscall_event_on_all_cpus(void)
 		}
 
 		expected = nr_openat_calls + cpu;
-		if (evsel->counts->cpu[cpu].val != expected) {
+		if (perf_counts(evsel->counts, cpu)->val != expected) {
 			pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
-				 expected, cpus->map[cpu], evsel->counts->cpu[cpu].val);
+				 expected, cpus->map[cpu], perf_counts(evsel->counts, cpu)->val);
 			err = -1;
 		}
 	}
tools/perf/tests/openat-syscall.c +1 -1
index bdfa1f4..e86fc47 100644
@@ -44,7 +44,7 @@ int test__openat_syscall_event(void)
 		goto out_close_fd;
 	}
 
-	if (evsel->counts->cpu[0].val != nr_openat_calls) {
+	if (perf_counts(evsel->counts, 0)->val != nr_openat_calls) {
 		pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
 			 nr_openat_calls, evsel->counts->cpu[0].val);
 		goto out_close_fd;
tools/perf/util/evsel.c +3 -3
index 1b2f480..8401b04 100644
@@ -910,8 +910,8 @@ void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
 		tmp = evsel->prev_raw_counts->aggr;
 		evsel->prev_raw_counts->aggr = *count;
 	} else {
-		tmp = evsel->prev_raw_counts->cpu[cpu];
-		evsel->prev_raw_counts->cpu[cpu] = *count;
+		tmp = *perf_counts(evsel->prev_raw_counts, cpu);
+		*perf_counts(evsel->prev_raw_counts, cpu) = *count;
 	}
 
 	count->val = count->val - tmp.val;
@@ -972,7 +972,7 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
 
 	perf_evsel__compute_deltas(evsel, cpu, &count);
 	perf_counts_values__scale(&count, scale, NULL);
-	evsel->counts->cpu[cpu] = count;
+	*perf_counts(evsel->counts, cpu) = count;
 	return 0;
 }
 
tools/perf/util/evsel.h +1 -17
index 4dbf32d..b420f8f 100644
@@ -9,23 +9,7 @@
 #include "xyarray.h"
 #include "symbol.h"
 #include "cpumap.h"
-
-struct perf_counts_values {
-	union {
-		struct {
-			u64 val;
-			u64 ena;
-			u64 run;
-		};
-		u64 values[3];
-	};
-};
-
-struct perf_counts {
-	s8		   	  scaled;
-	struct perf_counts_values aggr;
-	struct perf_counts_values cpu[];
-};
+#include "stat.h"
 
 struct perf_evsel;
 
tools/perf/util/stat.h +23 -0
index 093dc3c..5e43348 100644
@@ -31,6 +31,29 @@ enum aggr_mode {
 	AGGR_CORE,
 };
 
+struct perf_counts_values {
+	union {
+		struct {
+			u64 val;
+			u64 ena;
+			u64 run;
+		};
+		u64 values[3];
+	};
+};
+
+struct perf_counts {
+	s8			  scaled;
+	struct perf_counts_values aggr;
+	struct perf_counts_values cpu[];
+};
+
+static inline struct perf_counts_values*
+perf_counts(struct perf_counts *counts, int cpu)
+{
+	return &counts->cpu[cpu];
+}
+
 void update_stats(struct stats *stats, u64 val);
 double avg_stats(struct stats *stats);
 double stddev_stats(struct stats *stats);
author reviewer
#10 lore raw

PATCH v5 5/22 perf stat: Use xyarray for cpu evsel counts

In reply to Jiri Olsa

Switching single dimensional array of 'struct perf_counts_values' with xyarray object, so we could store thread dimension counts.

---
 tools/perf/builtin-stat.c         |  2 +-
 tools/perf/tests/openat-syscall.c |  2 +-
 tools/perf/util/stat.c            | 31 ++++++++++++++++++++++---------
 tools/perf/util/stat.h            |  7 ++++---
 4 files changed, 28 insertions(+), 14 deletions(-)
tools/perf/builtin-stat.c +1 -1
index 49b90374232c..055ce83dd6f2 100644
@@ -218,7 +218,7 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
 
 	evlist__for_each(evlist, evsel) {
 		perf_evsel__reset_stat_priv(evsel);
-		perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
+		perf_evsel__reset_counts(evsel);
 	}
 
 	perf_stat__reset_shadow_stats();
tools/perf/tests/openat-syscall.c +1 -1
index e86fc477a74f..bd882f09ebbc 100644
@@ -46,7 +46,7 @@ int test__openat_syscall_event(void)
 
 	if (perf_counts(evsel->counts, 0)->val != nr_openat_calls) {
 		pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
-			 nr_openat_calls, evsel->counts->cpu[0].val);
+			 nr_openat_calls, perf_counts(evsel->counts, 0)->val);
 		goto out_close_fd;
 	}
 
tools/perf/util/stat.c +22 -9
index 4014b709f956..453480aa7650 100644
@@ -97,26 +97,39 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)
 
 struct perf_counts *perf_counts__new(int ncpus)
 {
-	int size = sizeof(struct perf_counts) +
-		   ncpus * sizeof(struct perf_counts_values);
+	struct perf_counts *counts = zalloc(sizeof(*counts));
 
-	return zalloc(size);
+	if (counts) {
+		struct xyarray *cpu;
+
+		cpu = xyarray__new(ncpus, 1, sizeof(struct perf_counts_values));
+		if (!cpu) {
+			free(counts);
+			return NULL;
+		}
+
+		counts->cpu = cpu;
+	}
+
+	return counts;
 }
 
 void perf_counts__delete(struct perf_counts *counts)
 {
-	free(counts);
+	if (counts) {
+		xyarray__delete(counts->cpu);
+		free(counts);
+	}
 }
 
-static void perf_counts__reset(struct perf_counts *counts, int ncpus)
+static void perf_counts__reset(struct perf_counts *counts)
 {
-	memset(counts, 0, (sizeof(*counts) +
-	       (ncpus * sizeof(struct perf_counts_values))));
+	xyarray__reset(counts->cpu);
 }
 
-void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
+void perf_evsel__reset_counts(struct perf_evsel *evsel)
 {
-	perf_counts__reset(evsel->counts, ncpus);
+	perf_counts__reset(evsel->counts);
 }
 
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
tools/perf/util/stat.h +4 -3
index 5e43348836a6..6d07612545e0 100644
@@ -3,6 +3,7 @@
 
 #include <linux/types.h>
 #include <stdio.h>
+#include "xyarray.h"
 
 struct stats
 {
@@ -45,13 +46,13 @@ struct perf_counts_values {
 struct perf_counts {
 	s8			  scaled;
 	struct perf_counts_values aggr;
-	struct perf_counts_values cpu[];
+	struct xyarray		  *cpu;
 };
 
 static inline struct perf_counts_values*
 perf_counts(struct perf_counts *counts, int cpu)
 {
-	return &counts->cpu[cpu];
+	return xyarray__entry(counts->cpu, cpu, 0);
 }
 
 void update_stats(struct stats *stats, u64 val);
@@ -88,7 +89,7 @@ void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
 struct perf_counts *perf_counts__new(int ncpus);
 void perf_counts__delete(struct perf_counts *counts);
 
-void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus);
+void perf_evsel__reset_counts(struct perf_evsel *evsel);
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
 void perf_evsel__free_counts(struct perf_evsel *evsel);
 #endif
Signature · 1 line
1.9.3
#11 lore raw

[tip:perf/urgent] perf stat: Use xyarray for cpu evsel counts

perf stat: Use xyarray for cpu evsel counts
Commit-ID:  a8e02324dfe6bcafc15d02b790f33321ec4facb0
Gitweb:     http://git.kernel.org/tip/a8e02324dfe6bcafc15d02b790f33321ec4facb0
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:10 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:19:19 -0300

perf stat: Use xyarray for cpu evsel counts

Switching single dimensional array of 'struct perf_counts_values' with xyarray object, so we could store thread dimension counts.

---
 tools/perf/builtin-stat.c         |  2 +-
 tools/perf/tests/openat-syscall.c |  2 +-
 tools/perf/util/stat.c            | 31 ++++++++++++++++++++++---------
 tools/perf/util/stat.h            |  7 ++++---
 4 files changed, 28 insertions(+), 14 deletions(-)
tools/perf/builtin-stat.c +1 -1
index 49b9037..055ce83 100644
@@ -218,7 +218,7 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
 
 	evlist__for_each(evlist, evsel) {
 		perf_evsel__reset_stat_priv(evsel);
-		perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
+		perf_evsel__reset_counts(evsel);
 	}
 
 	perf_stat__reset_shadow_stats();
tools/perf/tests/openat-syscall.c +1 -1
index e86fc47..bd882f0 100644
@@ -46,7 +46,7 @@ int test__openat_syscall_event(void)
 
 	if (perf_counts(evsel->counts, 0)->val != nr_openat_calls) {
 		pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
-			 nr_openat_calls, evsel->counts->cpu[0].val);
+			 nr_openat_calls, perf_counts(evsel->counts, 0)->val);
 		goto out_close_fd;
 	}
 
tools/perf/util/stat.c +22 -9
index 4014b70..453480a 100644
@@ -97,26 +97,39 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)
 
 struct perf_counts *perf_counts__new(int ncpus)
 {
-	int size = sizeof(struct perf_counts) +
-		   ncpus * sizeof(struct perf_counts_values);
+	struct perf_counts *counts = zalloc(sizeof(*counts));
 
-	return zalloc(size);
+	if (counts) {
+		struct xyarray *cpu;
+
+		cpu = xyarray__new(ncpus, 1, sizeof(struct perf_counts_values));
+		if (!cpu) {
+			free(counts);
+			return NULL;
+		}
+
+		counts->cpu = cpu;
+	}
+
+	return counts;
 }
 
 void perf_counts__delete(struct perf_counts *counts)
 {
-	free(counts);
+	if (counts) {
+		xyarray__delete(counts->cpu);
+		free(counts);
+	}
 }
 
-static void perf_counts__reset(struct perf_counts *counts, int ncpus)
+static void perf_counts__reset(struct perf_counts *counts)
 {
-	memset(counts, 0, (sizeof(*counts) +
-	       (ncpus * sizeof(struct perf_counts_values))));
+	xyarray__reset(counts->cpu);
 }
 
-void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
+void perf_evsel__reset_counts(struct perf_evsel *evsel)
 {
-	perf_counts__reset(evsel->counts, ncpus);
+	perf_counts__reset(evsel->counts);
 }
 
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
tools/perf/util/stat.h +4 -3
index 5e43348..6d07612 100644
@@ -3,6 +3,7 @@
 
 #include <linux/types.h>
 #include <stdio.h>
+#include "xyarray.h"
 
 struct stats
 {
@@ -45,13 +46,13 @@ struct perf_counts_values {
 struct perf_counts {
 	s8			  scaled;
 	struct perf_counts_values aggr;
-	struct perf_counts_values cpu[];
+	struct xyarray		  *cpu;
 };
 
 static inline struct perf_counts_values*
 perf_counts(struct perf_counts *counts, int cpu)
 {
-	return &counts->cpu[cpu];
+	return xyarray__entry(counts->cpu, cpu, 0);
 }
 
 void update_stats(struct stats *stats, u64 val);
@@ -88,7 +89,7 @@ void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
 struct perf_counts *perf_counts__new(int ncpus);
 void perf_counts__delete(struct perf_counts *counts);
 
-void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus);
+void perf_evsel__reset_counts(struct perf_evsel *evsel);
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
 void perf_evsel__free_counts(struct perf_evsel *evsel);
 #endif
author reviewer
#12 lore raw

PATCH v5 6/22 perf stat: Make stats work over the thread dimension

In reply to Jiri Olsa

Now that we have space for thread dimension counts, let's store it.

---
 tools/perf/builtin-stat.c                  | 32 +++++++++++++++++-------------
 tools/perf/tests/openat-syscall-all-cpus.c |  6 +++---
 tools/perf/tests/openat-syscall.c          |  4 ++--
 tools/perf/util/evsel.c                    | 12 +++++------
 tools/perf/util/evsel.h                    |  2 +-
 tools/perf/util/stat.c                     |  8 ++++----
 tools/perf/util/stat.h                     |  8 ++++----
 7 files changed, 38 insertions(+), 34 deletions(-)
tools/perf/builtin-stat.c +18 -14
index 055ce83dd6f2..983bcbbe8e0a 100644
@@ -166,11 +166,12 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
 	zfree(&evsel->priv);
 }
 
-static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
+static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
+					     int ncpus, int nthreads)
 {
 	struct perf_counts *counts;
 
-	counts = perf_counts__new(perf_evsel__nr_cpus(evsel));
+	counts = perf_counts__new(ncpus, nthreads);
 	if (counts)
 		evsel->prev_raw_counts = counts;
 
@@ -197,11 +198,14 @@ static void perf_evlist__free_stats(struct perf_evlist *evlist)
 static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
 {
 	struct perf_evsel *evsel;
+	int nthreads = thread_map__nr(evsel_list->threads);
 
 	evlist__for_each(evlist, evsel) {
+		int ncpus = perf_evsel__nr_cpus(evsel);
+
 		if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
-		    perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 ||
-		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0))
+		    perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
+		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
 			goto out_free;
 	}
 
@@ -294,7 +298,7 @@ static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
 	return 0;
 }
 
-static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
+static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
 		   struct perf_counts_values *count)
 {
 	struct perf_counts_values *aggr = &evsel->counts->aggr;
@@ -314,9 +318,9 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
 	case AGGR_SOCKET:
 	case AGGR_NONE:
 		if (!evsel->snapshot)
-			perf_evsel__compute_deltas(evsel, cpu, count);
+			perf_evsel__compute_deltas(evsel, cpu, thread, count);
 		perf_counts_values__scale(count, scale, NULL);
-		*perf_counts(evsel->counts, cpu) = *count;
+		*perf_counts(evsel->counts, cpu, thread) = *count;
 		if (aggr_mode == AGGR_NONE)
 			perf_stat__update_shadow_stats(evsel, count->values, cpu);
 		break;
@@ -352,7 +356,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
 		return -1;
 
 	if (!counter->snapshot)
-		perf_evsel__compute_deltas(counter, -1, aggr);
+		perf_evsel__compute_deltas(counter, -1, -1, aggr);
 	perf_counts_values__scale(aggr, scale, &counter->counts->scaled);
 
 	for (i = 0; i < 3; i++)
@@ -805,9 +809,9 @@ static void print_aggr(char *prefix)
 				s2 = aggr_get_id(evsel_list->cpus, cpu2);
 				if (s2 != id)
 					continue;
-				val += perf_counts(counter->counts, cpu)->val;
-				ena += perf_counts(counter->counts, cpu)->ena;
-				run += perf_counts(counter->counts, cpu)->run;
+				val += perf_counts(counter->counts, cpu, 0)->val;
+				ena += perf_counts(counter->counts, cpu, 0)->ena;
+				run += perf_counts(counter->counts, cpu, 0)->run;
 				nr++;
 			}
 			if (prefix)
@@ -915,9 +919,9 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
 	int cpu;
 
 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
-		val = perf_counts(counter->counts, cpu)->val;
-		ena = perf_counts(counter->counts, cpu)->ena;
-		run = perf_counts(counter->counts, cpu)->run;
+		val = perf_counts(counter->counts, cpu, 0)->val;
+		ena = perf_counts(counter->counts, cpu, 0)->ena;
+		run = perf_counts(counter->counts, cpu, 0)->run;
 
 		if (prefix)
 			fprintf(output, "%s", prefix);
tools/perf/tests/openat-syscall-all-cpus.c +3 -3
index e8d944fe1bd0..a572f87e9c8d 100644
@@ -78,7 +78,7 @@ int test__openat_syscall_event_on_all_cpus(void)
 	 * we use the auto allocation it will allocate just for 1 cpu,
 	 * as we start by cpu 0.
 	 */
-	if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) {
+	if (perf_evsel__alloc_counts(evsel, cpus->nr, 1) < 0) {
 		pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
 		goto out_close_fd;
 	}
@@ -98,9 +98,9 @@ int test__openat_syscall_event_on_all_cpus(void)
 		}
 
 		expected = nr_openat_calls + cpu;
-		if (perf_counts(evsel->counts, cpu)->val != expected) {
+		if (perf_counts(evsel->counts, cpu, 0)->val != expected) {
 			pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
-				 expected, cpus->map[cpu], perf_counts(evsel->counts, cpu)->val);
+				 expected, cpus->map[cpu], perf_counts(evsel->counts, cpu, 0)->val);
 			err = -1;
 		}
 	}
tools/perf/tests/openat-syscall.c +2 -2
index bd882f09ebbc..c9a37bc6b33a 100644
@@ -44,9 +44,9 @@ int test__openat_syscall_event(void)
 		goto out_close_fd;
 	}
 
-	if (perf_counts(evsel->counts, 0)->val != nr_openat_calls) {
+	if (perf_counts(evsel->counts, 0, 0)->val != nr_openat_calls) {
 		pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
-			 nr_openat_calls, perf_counts(evsel->counts, 0)->val);
+			 nr_openat_calls, perf_counts(evsel->counts, 0, 0)->val);
 		goto out_close_fd;
 	}
 
tools/perf/util/evsel.c +6 -6
index 8401b042b9d4..cd6ce7066f85 100644
@@ -898,7 +898,7 @@ void perf_evsel__delete(struct perf_evsel *evsel)
 	free(evsel);
 }
 
-void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
+void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu, int thread,
 				struct perf_counts_values *count)
 {
 	struct perf_counts_values tmp;
@@ -910,8 +910,8 @@ void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
 		tmp = evsel->prev_raw_counts->aggr;
 		evsel->prev_raw_counts->aggr = *count;
 	} else {
-		tmp = *perf_counts(evsel->prev_raw_counts, cpu);
-		*perf_counts(evsel->prev_raw_counts, cpu) = *count;
+		tmp = *perf_counts(evsel->prev_raw_counts, cpu, thread);
+		*perf_counts(evsel->prev_raw_counts, cpu, thread) = *count;
 	}
 
 	count->val = count->val - tmp.val;
@@ -964,15 +964,15 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
 	if (FD(evsel, cpu, thread) < 0)
 		return -EINVAL;
 
-	if (evsel->counts == NULL && perf_evsel__alloc_counts(evsel, cpu + 1) < 0)
+	if (evsel->counts == NULL && perf_evsel__alloc_counts(evsel, cpu + 1, thread + 1) < 0)
 		return -ENOMEM;
 
 	if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) < 0)
 		return -errno;
 
-	perf_evsel__compute_deltas(evsel, cpu, &count);
+	perf_evsel__compute_deltas(evsel, cpu, thread, &count);
 	perf_counts_values__scale(&count, scale, NULL);
-	*perf_counts(evsel->counts, cpu) = count;
+	*perf_counts(evsel->counts, cpu, thread) = count;
 	return 0;
 }
 
tools/perf/util/evsel.h +1 -1
index b420f8f5fc5d..020f7e13634a 100644
@@ -112,7 +112,7 @@ static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
 void perf_counts_values__scale(struct perf_counts_values *count,
 			       bool scale, s8 *pscaled);
 
-void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
+void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu, int thread,
 				struct perf_counts_values *count);
 
 int perf_evsel__object_config(size_t object_size,
tools/perf/util/stat.c +4 -4
index 453480aa7650..7bcc19b62dd1 100644
@@ -95,14 +95,14 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)
 	}
 }
 
-struct perf_counts *perf_counts__new(int ncpus)
+struct perf_counts *perf_counts__new(int ncpus, int nthreads)
 {
 	struct perf_counts *counts = zalloc(sizeof(*counts));
 
 	if (counts) {
 		struct xyarray *cpu;
 
-		cpu = xyarray__new(ncpus, 1, sizeof(struct perf_counts_values));
+		cpu = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
 		if (!cpu) {
 			free(counts);
 			return NULL;
@@ -132,9 +132,9 @@ void perf_evsel__reset_counts(struct perf_evsel *evsel)
 	perf_counts__reset(evsel->counts);
 }
 
-int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
+int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads)
 {
-	evsel->counts = perf_counts__new(ncpus);
+	evsel->counts = perf_counts__new(ncpus, nthreads);
 	return evsel->counts != NULL ? 0 : -ENOMEM;
 }
 
tools/perf/util/stat.h +4 -4
index 6d07612545e0..e0b8dc50fbb6 100644
@@ -50,9 +50,9 @@ struct perf_counts {
 };
 
 static inline struct perf_counts_values*
-perf_counts(struct perf_counts *counts, int cpu)
+perf_counts(struct perf_counts *counts, int cpu, int thread)
 {
-	return xyarray__entry(counts->cpu, cpu, 0);
+	return xyarray__entry(counts->cpu, cpu, thread);
 }
 
 void update_stats(struct stats *stats, u64 val);
@@ -86,10 +86,10 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
 void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
 				   double avg, int cpu, enum aggr_mode aggr);
 
-struct perf_counts *perf_counts__new(int ncpus);
+struct perf_counts *perf_counts__new(int ncpus, int nthreads);
 void perf_counts__delete(struct perf_counts *counts);
 
 void perf_evsel__reset_counts(struct perf_evsel *evsel);
-int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
+int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads);
 void perf_evsel__free_counts(struct perf_evsel *evsel);
 #endif
Signature · 1 line
1.9.3
#13 lore raw

[tip:perf/urgent] perf stat: Make stats work over the thread dimension

perf stat: Make stats work over the thread dimension
Commit-ID:  a6fa003855d38d53d90c1a8a5827102e62702334
Gitweb:     http://git.kernel.org/tip/a6fa003855d38d53d90c1a8a5827102e62702334
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:11 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:20:02 -0300

perf stat: Make stats work over the thread dimension

Now that we have space for thread dimension counts, let's store it.

---
 tools/perf/builtin-stat.c                  | 32 +++++++++++++++++-------------
 tools/perf/tests/openat-syscall-all-cpus.c |  6 +++---
 tools/perf/tests/openat-syscall.c          |  4 ++--
 tools/perf/util/evsel.c                    | 12 +++++------
 tools/perf/util/evsel.h                    |  2 +-
 tools/perf/util/stat.c                     |  8 ++++----
 tools/perf/util/stat.h                     |  8 ++++----
 7 files changed, 38 insertions(+), 34 deletions(-)
tools/perf/builtin-stat.c +18 -14
index 055ce83..983bcbb 100644
@@ -166,11 +166,12 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
 	zfree(&evsel->priv);
 }
 
-static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
+static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
+					     int ncpus, int nthreads)
 {
 	struct perf_counts *counts;
 
-	counts = perf_counts__new(perf_evsel__nr_cpus(evsel));
+	counts = perf_counts__new(ncpus, nthreads);
 	if (counts)
 		evsel->prev_raw_counts = counts;
 
@@ -197,11 +198,14 @@ static void perf_evlist__free_stats(struct perf_evlist *evlist)
 static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
 {
 	struct perf_evsel *evsel;
+	int nthreads = thread_map__nr(evsel_list->threads);
 
 	evlist__for_each(evlist, evsel) {
+		int ncpus = perf_evsel__nr_cpus(evsel);
+
 		if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
-		    perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 ||
-		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0))
+		    perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
+		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
 			goto out_free;
 	}
 
@@ -294,7 +298,7 @@ static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
 	return 0;
 }
 
-static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
+static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
 		   struct perf_counts_values *count)
 {
 	struct perf_counts_values *aggr = &evsel->counts->aggr;
@@ -314,9 +318,9 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread __maybe_unused,
 	case AGGR_SOCKET:
 	case AGGR_NONE:
 		if (!evsel->snapshot)
-			perf_evsel__compute_deltas(evsel, cpu, count);
+			perf_evsel__compute_deltas(evsel, cpu, thread, count);
 		perf_counts_values__scale(count, scale, NULL);
-		*perf_counts(evsel->counts, cpu) = *count;
+		*perf_counts(evsel->counts, cpu, thread) = *count;
 		if (aggr_mode == AGGR_NONE)
 			perf_stat__update_shadow_stats(evsel, count->values, cpu);
 		break;
@@ -352,7 +356,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
 		return -1;
 
 	if (!counter->snapshot)
-		perf_evsel__compute_deltas(counter, -1, aggr);
+		perf_evsel__compute_deltas(counter, -1, -1, aggr);
 	perf_counts_values__scale(aggr, scale, &counter->counts->scaled);
 
 	for (i = 0; i < 3; i++)
@@ -805,9 +809,9 @@ static void print_aggr(char *prefix)
 				s2 = aggr_get_id(evsel_list->cpus, cpu2);
 				if (s2 != id)
 					continue;
-				val += perf_counts(counter->counts, cpu)->val;
-				ena += perf_counts(counter->counts, cpu)->ena;
-				run += perf_counts(counter->counts, cpu)->run;
+				val += perf_counts(counter->counts, cpu, 0)->val;
+				ena += perf_counts(counter->counts, cpu, 0)->ena;
+				run += perf_counts(counter->counts, cpu, 0)->run;
 				nr++;
 			}
 			if (prefix)
@@ -915,9 +919,9 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
 	int cpu;
 
 	for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
-		val = perf_counts(counter->counts, cpu)->val;
-		ena = perf_counts(counter->counts, cpu)->ena;
-		run = perf_counts(counter->counts, cpu)->run;
+		val = perf_counts(counter->counts, cpu, 0)->val;
+		ena = perf_counts(counter->counts, cpu, 0)->ena;
+		run = perf_counts(counter->counts, cpu, 0)->run;
 
 		if (prefix)
 			fprintf(output, "%s", prefix);
tools/perf/tests/openat-syscall-all-cpus.c +3 -3
index e8d944f..a572f87 100644
@@ -78,7 +78,7 @@ int test__openat_syscall_event_on_all_cpus(void)
 	 * we use the auto allocation it will allocate just for 1 cpu,
 	 * as we start by cpu 0.
 	 */
-	if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) {
+	if (perf_evsel__alloc_counts(evsel, cpus->nr, 1) < 0) {
 		pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
 		goto out_close_fd;
 	}
@@ -98,9 +98,9 @@ int test__openat_syscall_event_on_all_cpus(void)
 		}
 
 		expected = nr_openat_calls + cpu;
-		if (perf_counts(evsel->counts, cpu)->val != expected) {
+		if (perf_counts(evsel->counts, cpu, 0)->val != expected) {
 			pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
-				 expected, cpus->map[cpu], perf_counts(evsel->counts, cpu)->val);
+				 expected, cpus->map[cpu], perf_counts(evsel->counts, cpu, 0)->val);
 			err = -1;
 		}
 	}
tools/perf/tests/openat-syscall.c +2 -2
index bd882f0..c9a37bc 100644
@@ -44,9 +44,9 @@ int test__openat_syscall_event(void)
 		goto out_close_fd;
 	}
 
-	if (perf_counts(evsel->counts, 0)->val != nr_openat_calls) {
+	if (perf_counts(evsel->counts, 0, 0)->val != nr_openat_calls) {
 		pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
-			 nr_openat_calls, perf_counts(evsel->counts, 0)->val);
+			 nr_openat_calls, perf_counts(evsel->counts, 0, 0)->val);
 		goto out_close_fd;
 	}
 
tools/perf/util/evsel.c +6 -6
index 8401b04..cd6ce70 100644
@@ -898,7 +898,7 @@ void perf_evsel__delete(struct perf_evsel *evsel)
 	free(evsel);
 }
 
-void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
+void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu, int thread,
 				struct perf_counts_values *count)
 {
 	struct perf_counts_values tmp;
@@ -910,8 +910,8 @@ void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
 		tmp = evsel->prev_raw_counts->aggr;
 		evsel->prev_raw_counts->aggr = *count;
 	} else {
-		tmp = *perf_counts(evsel->prev_raw_counts, cpu);
-		*perf_counts(evsel->prev_raw_counts, cpu) = *count;
+		tmp = *perf_counts(evsel->prev_raw_counts, cpu, thread);
+		*perf_counts(evsel->prev_raw_counts, cpu, thread) = *count;
 	}
 
 	count->val = count->val - tmp.val;
@@ -964,15 +964,15 @@ int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
 	if (FD(evsel, cpu, thread) < 0)
 		return -EINVAL;
 
-	if (evsel->counts == NULL && perf_evsel__alloc_counts(evsel, cpu + 1) < 0)
+	if (evsel->counts == NULL && perf_evsel__alloc_counts(evsel, cpu + 1, thread + 1) < 0)
 		return -ENOMEM;
 
 	if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) < 0)
 		return -errno;
 
-	perf_evsel__compute_deltas(evsel, cpu, &count);
+	perf_evsel__compute_deltas(evsel, cpu, thread, &count);
 	perf_counts_values__scale(&count, scale, NULL);
-	*perf_counts(evsel->counts, cpu) = count;
+	*perf_counts(evsel->counts, cpu, thread) = count;
 	return 0;
 }
 
tools/perf/util/evsel.h +1 -1
index b420f8f..020f7e1 100644
@@ -112,7 +112,7 @@ static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
 void perf_counts_values__scale(struct perf_counts_values *count,
 			       bool scale, s8 *pscaled);
 
-void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
+void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu, int thread,
 				struct perf_counts_values *count);
 
 int perf_evsel__object_config(size_t object_size,
tools/perf/util/stat.c +4 -4
index 453480a..7bcc19b 100644
@@ -95,14 +95,14 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)
 	}
 }
 
-struct perf_counts *perf_counts__new(int ncpus)
+struct perf_counts *perf_counts__new(int ncpus, int nthreads)
 {
 	struct perf_counts *counts = zalloc(sizeof(*counts));
 
 	if (counts) {
 		struct xyarray *cpu;
 
-		cpu = xyarray__new(ncpus, 1, sizeof(struct perf_counts_values));
+		cpu = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
 		if (!cpu) {
 			free(counts);
 			return NULL;
@@ -132,9 +132,9 @@ void perf_evsel__reset_counts(struct perf_evsel *evsel)
 	perf_counts__reset(evsel->counts);
 }
 
-int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
+int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads)
 {
-	evsel->counts = perf_counts__new(ncpus);
+	evsel->counts = perf_counts__new(ncpus, nthreads);
 	return evsel->counts != NULL ? 0 : -ENOMEM;
 }
 
tools/perf/util/stat.h +4 -4
index 6d07612..e0b8dc5 100644
@@ -50,9 +50,9 @@ struct perf_counts {
 };
 
 static inline struct perf_counts_values*
-perf_counts(struct perf_counts *counts, int cpu)
+perf_counts(struct perf_counts *counts, int cpu, int thread)
 {
-	return xyarray__entry(counts->cpu, cpu, 0);
+	return xyarray__entry(counts->cpu, cpu, thread);
 }
 
 void update_stats(struct stats *stats, u64 val);
@@ -86,10 +86,10 @@ void perf_stat__update_shadow_stats(struct perf_evsel *counter, u64 *count,
 void perf_stat__print_shadow_stats(FILE *out, struct perf_evsel *evsel,
 				   double avg, int cpu, enum aggr_mode aggr);
 
-struct perf_counts *perf_counts__new(int ncpus);
+struct perf_counts *perf_counts__new(int ncpus, int nthreads);
 void perf_counts__delete(struct perf_counts *counts);
 
 void perf_evsel__reset_counts(struct perf_evsel *evsel);
-int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
+int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads);
 void perf_evsel__free_counts(struct perf_evsel *evsel);
 #endif
author reviewer
#14 lore raw

PATCH v5 7/22 perf stat: Rename struct perf_counts::cpu member to values

In reply to Jiri Olsa

Renaming 'struct xyarray *cpu' pointer to more fitting/generic values, because now we store both cpu and thread values.

---
 tools/perf/util/stat.c | 12 ++++++------
 tools/perf/util/stat.h |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)
tools/perf/util/stat.c +6 -6
index 7bcc19b62dd1..197a2db5f2c4 100644
@@ -100,15 +100,15 @@ struct perf_counts *perf_counts__new(int ncpus, int nthreads)
 	struct perf_counts *counts = zalloc(sizeof(*counts));
 
 	if (counts) {
-		struct xyarray *cpu;
+		struct xyarray *values;
 
-		cpu = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
-		if (!cpu) {
+		values = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
+		if (!values) {
 			free(counts);
 			return NULL;
 		}
 
-		counts->cpu = cpu;
+		counts->values = values;
 	}
 
 	return counts;
@@ -117,14 +117,14 @@ struct perf_counts *perf_counts__new(int ncpus, int nthreads)
 void perf_counts__delete(struct perf_counts *counts)
 {
 	if (counts) {
-		xyarray__delete(counts->cpu);
+		xyarray__delete(counts->values);
 		free(counts);
 	}
 }
 
 static void perf_counts__reset(struct perf_counts *counts)
 {
-	xyarray__reset(counts->cpu);
+	xyarray__reset(counts->values);
 }
 
 void perf_evsel__reset_counts(struct perf_evsel *evsel)
tools/perf/util/stat.h +2 -2
index e0b8dc50fbb6..295d1e29d3d6 100644
@@ -46,13 +46,13 @@ struct perf_counts_values {
 struct perf_counts {
 	s8			  scaled;
 	struct perf_counts_values aggr;
-	struct xyarray		  *cpu;
+	struct xyarray		  *values;
 };
 
 static inline struct perf_counts_values*
 perf_counts(struct perf_counts *counts, int cpu, int thread)
 {
-	return xyarray__entry(counts->cpu, cpu, thread);
+	return xyarray__entry(counts->values, cpu, thread);
 }
 
 void update_stats(struct stats *stats, u64 val);
Signature · 1 line
1.9.3
#15 lore raw

[tip:perf/urgent] perf stat: Rename struct perf_counts:: cpu member to values

perf stat: Rename struct perf_counts::cpu member to values
Commit-ID:  57b289159ab4fe1f7b2b531464cf67f65e48dd00
Gitweb:     http://git.kernel.org/tip/57b289159ab4fe1f7b2b531464cf67f65e48dd00
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:12 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:25:03 -0300

perf stat: Rename struct perf_counts::cpu member to values

Renaming 'struct xyarray *cpu' pointer to more fitting/generic values, because now we store both cpu and thread values.

---
 tools/perf/util/stat.c | 12 ++++++------
 tools/perf/util/stat.h |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)
tools/perf/util/stat.c +6 -6
index 7bcc19b..197a2db 100644
@@ -100,15 +100,15 @@ struct perf_counts *perf_counts__new(int ncpus, int nthreads)
 	struct perf_counts *counts = zalloc(sizeof(*counts));
 
 	if (counts) {
-		struct xyarray *cpu;
+		struct xyarray *values;
 
-		cpu = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
-		if (!cpu) {
+		values = xyarray__new(ncpus, nthreads, sizeof(struct perf_counts_values));
+		if (!values) {
 			free(counts);
 			return NULL;
 		}
 
-		counts->cpu = cpu;
+		counts->values = values;
 	}
 
 	return counts;
@@ -117,14 +117,14 @@ struct perf_counts *perf_counts__new(int ncpus, int nthreads)
 void perf_counts__delete(struct perf_counts *counts)
 {
 	if (counts) {
-		xyarray__delete(counts->cpu);
+		xyarray__delete(counts->values);
 		free(counts);
 	}
 }
 
 static void perf_counts__reset(struct perf_counts *counts)
 {
-	xyarray__reset(counts->cpu);
+	xyarray__reset(counts->values);
 }
 
 void perf_evsel__reset_counts(struct perf_evsel *evsel)
tools/perf/util/stat.h +2 -2
index e0b8dc5..295d1e2 100644
@@ -46,13 +46,13 @@ struct perf_counts_values {
 struct perf_counts {
 	s8			  scaled;
 	struct perf_counts_values aggr;
-	struct xyarray		  *cpu;
+	struct xyarray		  *values;
 };
 
 static inline struct perf_counts_values*
 perf_counts(struct perf_counts *counts, int cpu, int thread)
 {
-	return xyarray__entry(counts->cpu, cpu, thread);
+	return xyarray__entry(counts->values, cpu, thread);
 }
 
 void update_stats(struct stats *stats, u64 val);
author reviewer
#16 lore raw

PATCH v5 8/22 perf stat: Introduce perf_evlist__reset_stats

In reply to Jiri Olsa

To fit in with the rest of the helpers (alloc and free).

---
 tools/perf/builtin-stat.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
tools/perf/builtin-stat.c +6 -2
index 983bcbbe8e0a..188cd98a4ab3 100644
@@ -216,7 +216,7 @@ out_free:
 	return -1;
 }
 
-static void perf_stat__reset_stats(struct perf_evlist *evlist)
+static void perf_evlist__reset_stats(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
 
@@ -224,7 +224,11 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
 		perf_evsel__reset_stat_priv(evsel);
 		perf_evsel__reset_counts(evsel);
 	}
+}
 
+static void perf_stat__reset_stats(void)
+{
+	perf_evlist__reset_stats(evsel_list);
 	perf_stat__reset_shadow_stats();
 }
 
@@ -1473,7 +1477,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 		status = run_perf_stat(argc, argv);
 		if (forever && status != -1) {
 			print_stat(argc, argv);
-			perf_stat__reset_stats(evsel_list);
+			perf_stat__reset_stats();
 		}
 	}
 
Signature · 1 line
1.9.3
#17 lore raw

[tip:perf/urgent] perf stat: Introduce perf_evlist__reset_stats

perf stat: Introduce perf_evlist__reset_stats
Commit-ID:  254ecbc7474dfa08155c5595e90cd4a0fa9d14ce
Gitweb:     http://git.kernel.org/tip/254ecbc7474dfa08155c5595e90cd4a0fa9d14ce
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:13 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:25:39 -0300

perf stat: Introduce perf_evlist__reset_stats

To fit in with the rest of the helpers (alloc and free).

---
 tools/perf/builtin-stat.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
tools/perf/builtin-stat.c +6 -2
index 983bcbb..188cd98a 100644
@@ -216,7 +216,7 @@ out_free:
 	return -1;
 }
 
-static void perf_stat__reset_stats(struct perf_evlist *evlist)
+static void perf_evlist__reset_stats(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
 
@@ -224,7 +224,11 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
 		perf_evsel__reset_stat_priv(evsel);
 		perf_evsel__reset_counts(evsel);
 	}
+}
 
+static void perf_stat__reset_stats(void)
+{
+	perf_evlist__reset_stats(evsel_list);
 	perf_stat__reset_shadow_stats();
 }
 
@@ -1473,7 +1477,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 		status = run_perf_stat(argc, argv);
 		if (forever && status != -1) {
 			print_stat(argc, argv);
-			perf_stat__reset_stats(evsel_list);
+			perf_stat__reset_stats();
 		}
 	}
 
author reviewer
#18 lore raw

PATCH v5 9/22 perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into stat object

In reply to Jiri Olsa

Moving perf_evsel__(alloc|free|reset)_stat_priv into stat object, so it could be used outside stat command in following patches.

---
 tools/perf/builtin-stat.c | 25 -------------------------
 tools/perf/util/stat.c    | 25 +++++++++++++++++++++++++
 tools/perf/util/stat.h    |  4 ++++
 3 files changed, 29 insertions(+), 25 deletions(-)
tools/perf/builtin-stat.c +0 -25
index 188cd98a4ab3..8a7fd0c60ab1 100644
@@ -141,31 +141,6 @@ static inline void diff_timespec(struct timespec *r, struct timespec *a,
 	}
 }
 
-static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
-{
-	int i;
-	struct perf_stat *ps = evsel->priv;
-
-	for (i = 0; i < 3; i++)
-		init_stats(&ps->res_stats[i]);
-
-	perf_stat_evsel_id_init(evsel);
-}
-
-static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
-{
-	evsel->priv = zalloc(sizeof(struct perf_stat));
-	if (evsel->priv == NULL)
-		return -ENOMEM;
-	perf_evsel__reset_stat_priv(evsel);
-	return 0;
-}
-
-static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
-{
-	zfree(&evsel->priv);
-}
-
 static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
 					     int ncpus, int nthreads)
 {
tools/perf/util/stat.c +25 -0
index 197a2db5f2c4..b8c329f41f13 100644
@@ -143,3 +143,28 @@ void perf_evsel__free_counts(struct perf_evsel *evsel)
 	perf_counts__delete(evsel->counts);
 	evsel->counts = NULL;
 }
+
+void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
+{
+	int i;
+	struct perf_stat *ps = evsel->priv;
+
+	for (i = 0; i < 3; i++)
+		init_stats(&ps->res_stats[i]);
+
+	perf_stat_evsel_id_init(evsel);
+}
+
+int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
+{
+	evsel->priv = zalloc(sizeof(struct perf_stat));
+	if (evsel->priv == NULL)
+		return -ENOMEM;
+	perf_evsel__reset_stat_priv(evsel);
+	return 0;
+}
+
+void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
+{
+	zfree(&evsel->priv);
+}
tools/perf/util/stat.h +4 -0
index 295d1e29d3d6..c441cb312565 100644
@@ -92,4 +92,8 @@ void perf_counts__delete(struct perf_counts *counts);
 void perf_evsel__reset_counts(struct perf_evsel *evsel);
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads);
 void perf_evsel__free_counts(struct perf_evsel *evsel);
+
+void perf_evsel__reset_stat_priv(struct perf_evsel *evsel);
+int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel);
+void perf_evsel__free_stat_priv(struct perf_evsel *evsel);
 #endif
Signature · 1 line
1.9.3
#19 lore raw

[tip:perf/urgent] perf stat: Move perf_evsel__(alloc|free|reset) _stat_priv into stat object

perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into stat object
Commit-ID:  9689edfabc1547155a7cdd1304fd294107054291
Gitweb:     http://git.kernel.org/tip/9689edfabc1547155a7cdd1304fd294107054291
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:14 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:26:44 -0300

perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into stat object

Moving perf_evsel__(alloc|free|reset)_stat_priv into stat object, so it could be used outside stat command in following patches.

---
 tools/perf/builtin-stat.c | 25 -------------------------
 tools/perf/util/stat.c    | 25 +++++++++++++++++++++++++
 tools/perf/util/stat.h    |  4 ++++
 3 files changed, 29 insertions(+), 25 deletions(-)
tools/perf/builtin-stat.c +0 -25
index 188cd98a..8a7fd0c 100644
@@ -141,31 +141,6 @@ static inline void diff_timespec(struct timespec *r, struct timespec *a,
 	}
 }
 
-static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
-{
-	int i;
-	struct perf_stat *ps = evsel->priv;
-
-	for (i = 0; i < 3; i++)
-		init_stats(&ps->res_stats[i]);
-
-	perf_stat_evsel_id_init(evsel);
-}
-
-static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
-{
-	evsel->priv = zalloc(sizeof(struct perf_stat));
-	if (evsel->priv == NULL)
-		return -ENOMEM;
-	perf_evsel__reset_stat_priv(evsel);
-	return 0;
-}
-
-static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
-{
-	zfree(&evsel->priv);
-}
-
 static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
 					     int ncpus, int nthreads)
 {
tools/perf/util/stat.c +25 -0
index 197a2db..b8c329f 100644
@@ -143,3 +143,28 @@ void perf_evsel__free_counts(struct perf_evsel *evsel)
 	perf_counts__delete(evsel->counts);
 	evsel->counts = NULL;
 }
+
+void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
+{
+	int i;
+	struct perf_stat *ps = evsel->priv;
+
+	for (i = 0; i < 3; i++)
+		init_stats(&ps->res_stats[i]);
+
+	perf_stat_evsel_id_init(evsel);
+}
+
+int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
+{
+	evsel->priv = zalloc(sizeof(struct perf_stat));
+	if (evsel->priv == NULL)
+		return -ENOMEM;
+	perf_evsel__reset_stat_priv(evsel);
+	return 0;
+}
+
+void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
+{
+	zfree(&evsel->priv);
+}
tools/perf/util/stat.h +4 -0
index 295d1e2..c441cb3 100644
@@ -92,4 +92,8 @@ void perf_counts__delete(struct perf_counts *counts);
 void perf_evsel__reset_counts(struct perf_evsel *evsel);
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads);
 void perf_evsel__free_counts(struct perf_evsel *evsel);
+
+void perf_evsel__reset_stat_priv(struct perf_evsel *evsel);
+int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel);
+void perf_evsel__free_stat_priv(struct perf_evsel *evsel);
 #endif
author reviewer
#20 lore raw

PATCH v5 10/22 perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts into stat object

In reply to Jiri Olsa

Moving perf_evsel__(alloc|free)_prev_raw_counts into stat object, so it could be used in following patches.

---
 tools/perf/builtin-stat.c | 18 ------------------
 tools/perf/util/stat.c    | 18 ++++++++++++++++++
 tools/perf/util/stat.h    |  4 ++++
 3 files changed, 22 insertions(+), 18 deletions(-)
tools/perf/builtin-stat.c +0 -18
index 8a7fd0c60ab1..0ccba5c6b61d 100644
@@ -141,24 +141,6 @@ static inline void diff_timespec(struct timespec *r, struct timespec *a,
 	}
 }
 
-static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
-					     int ncpus, int nthreads)
-{
-	struct perf_counts *counts;
-
-	counts = perf_counts__new(ncpus, nthreads);
-	if (counts)
-		evsel->prev_raw_counts = counts;
-
-	return counts ? 0 : -ENOMEM;
-}
-
-static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
-{
-	perf_counts__delete(evsel->prev_raw_counts);
-	evsel->prev_raw_counts = NULL;
-}
-
 static void perf_evlist__free_stats(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
tools/perf/util/stat.c +18 -0
index b8c329f41f13..6221c3898397 100644
@@ -168,3 +168,21 @@ void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
 {
 	zfree(&evsel->priv);
 }
+
+int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
+				      int ncpus, int nthreads)
+{
+	struct perf_counts *counts;
+
+	counts = perf_counts__new(ncpus, nthreads);
+	if (counts)
+		evsel->prev_raw_counts = counts;
+
+	return counts ? 0 : -ENOMEM;
+}
+
+void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
+{
+	perf_counts__delete(evsel->prev_raw_counts);
+	evsel->prev_raw_counts = NULL;
+}
tools/perf/util/stat.h +4 -0
index c441cb312565..454b26875aef 100644
@@ -96,4 +96,8 @@ void perf_evsel__free_counts(struct perf_evsel *evsel);
 void perf_evsel__reset_stat_priv(struct perf_evsel *evsel);
 int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel);
 void perf_evsel__free_stat_priv(struct perf_evsel *evsel);
+
+int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
+				      int ncpus, int nthreads);
+void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel);
 #endif
Signature · 1 line
1.9.3
#21 lore raw

[tip:perf/urgent] perf stat: Move perf_evsel__(alloc|free) _prev_raw_counts into stat object

perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts into stat object
Commit-ID:  a939512d10a5583a32ae85c1bff6c4ae63a8a517
Gitweb:     http://git.kernel.org/tip/a939512d10a5583a32ae85c1bff6c4ae63a8a517
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:15 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:34:43 -0300

perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts into stat object

Moving perf_evsel__(alloc|free)_prev_raw_counts into stat object, so it could be used in following patches.

---
 tools/perf/builtin-stat.c | 18 ------------------
 tools/perf/util/stat.c    | 18 ++++++++++++++++++
 tools/perf/util/stat.h    |  4 ++++
 3 files changed, 22 insertions(+), 18 deletions(-)
tools/perf/builtin-stat.c +0 -18
index 8a7fd0c..0ccba5c 100644
@@ -141,24 +141,6 @@ static inline void diff_timespec(struct timespec *r, struct timespec *a,
 	}
 }
 
-static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
-					     int ncpus, int nthreads)
-{
-	struct perf_counts *counts;
-
-	counts = perf_counts__new(ncpus, nthreads);
-	if (counts)
-		evsel->prev_raw_counts = counts;
-
-	return counts ? 0 : -ENOMEM;
-}
-
-static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
-{
-	perf_counts__delete(evsel->prev_raw_counts);
-	evsel->prev_raw_counts = NULL;
-}
-
 static void perf_evlist__free_stats(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
tools/perf/util/stat.c +18 -0
index b8c329f..6221c38 100644
@@ -168,3 +168,21 @@ void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
 {
 	zfree(&evsel->priv);
 }
+
+int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
+				      int ncpus, int nthreads)
+{
+	struct perf_counts *counts;
+
+	counts = perf_counts__new(ncpus, nthreads);
+	if (counts)
+		evsel->prev_raw_counts = counts;
+
+	return counts ? 0 : -ENOMEM;
+}
+
+void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
+{
+	perf_counts__delete(evsel->prev_raw_counts);
+	evsel->prev_raw_counts = NULL;
+}
tools/perf/util/stat.h +4 -0
index c441cb3..454b268 100644
@@ -96,4 +96,8 @@ void perf_evsel__free_counts(struct perf_evsel *evsel);
 void perf_evsel__reset_stat_priv(struct perf_evsel *evsel);
 int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel);
 void perf_evsel__free_stat_priv(struct perf_evsel *evsel);
+
+int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
+				      int ncpus, int nthreads);
+void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel);
 #endif
author reviewer
#22 lore raw

PATCH v5 11/22 perf stat: Move perf_evlist__(alloc|free|reset)_stats into stat object

In reply to Jiri Olsa

Moving perf_evlist__(alloc|free|reset)_stats into stat object, so it could be used in following patches.

---
 tools/perf/builtin-stat.c | 42 ------------------------------------------
 tools/perf/util/evlist.h  |  1 -
 tools/perf/util/stat.c    | 44 ++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/stat.h    |  6 ++++++
 4 files changed, 50 insertions(+), 43 deletions(-)
tools/perf/builtin-stat.c +0 -42
index 0ccba5c6b61d..3e385f9f12ee 100644
@@ -141,48 +141,6 @@ static inline void diff_timespec(struct timespec *r, struct timespec *a,
 	}
 }
 
-static void perf_evlist__free_stats(struct perf_evlist *evlist)
-{
-	struct perf_evsel *evsel;
-
-	evlist__for_each(evlist, evsel) {
-		perf_evsel__free_stat_priv(evsel);
-		perf_evsel__free_counts(evsel);
-		perf_evsel__free_prev_raw_counts(evsel);
-	}
-}
-
-static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
-{
-	struct perf_evsel *evsel;
-	int nthreads = thread_map__nr(evsel_list->threads);
-
-	evlist__for_each(evlist, evsel) {
-		int ncpus = perf_evsel__nr_cpus(evsel);
-
-		if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
-		    perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
-		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
-			goto out_free;
-	}
-
-	return 0;
-
-out_free:
-	perf_evlist__free_stats(evlist);
-	return -1;
-}
-
-static void perf_evlist__reset_stats(struct perf_evlist *evlist)
-{
-	struct perf_evsel *evsel;
-
-	evlist__for_each(evlist, evsel) {
-		perf_evsel__reset_stat_priv(evsel);
-		perf_evsel__reset_counts(evsel);
-	}
-}
-
 static void perf_stat__reset_stats(void)
 {
 	perf_evlist__reset_stats(evsel_list);
tools/perf/util/evlist.h +0 -1
index a8489b9d2812..037633c1da9d 100644
@@ -289,5 +289,4 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
 
 void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
 				     struct perf_evsel *tracking_evsel);
-
 #endif /* __PERF_EVLIST_H */
tools/perf/util/stat.c +44 -0

53 lines not on this page · raw message

tools/perf/util/stat.h +6 -0
index 454b26875aef..5f62db2472c7 100644
@@ -70,6 +70,8 @@ static inline void init_stats(struct stats *stats)
 }
 
 struct perf_evsel;
+struct perf_evlist;
+
 bool __perf_evsel_stat__is(struct perf_evsel *evsel,
 			   enum perf_stat_evsel_id id);
 
@@ -100,4 +102,8 @@ void perf_evsel__free_stat_priv(struct perf_evsel *evsel);
 int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
 				      int ncpus, int nthreads);
 void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel);
+
+int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw);
+void perf_evlist__free_stats(struct perf_evlist *evlist);
+void perf_evlist__reset_stats(struct perf_evlist *evlist);
 #endif
Signature · 1 line
1.9.3
#23 lore raw

[tip:perf/urgent] perf stat: Move perf_evlist__(alloc|free|reset) _stats into stat object

perf stat: Move perf_evlist__(alloc|free|reset)_stats into stat object
Commit-ID:  24e34f68e21a47a582b3cc2eccdb835b80b1830a
Gitweb:     http://git.kernel.org/tip/24e34f68e21a47a582b3cc2eccdb835b80b1830a
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:16 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:44:37 -0300

perf stat: Move perf_evlist__(alloc|free|reset)_stats into stat object

Moving perf_evlist__(alloc|free|reset)_stats into stat object, so it could be used in following patches.

---
 tools/perf/builtin-stat.c | 42 ------------------------------------------
 tools/perf/util/evlist.h  |  1 -
 tools/perf/util/stat.c    | 44 ++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/stat.h    |  6 ++++++
 4 files changed, 50 insertions(+), 43 deletions(-)
tools/perf/builtin-stat.c +0 -42
index 0ccba5c..3e385f9 100644
@@ -141,48 +141,6 @@ static inline void diff_timespec(struct timespec *r, struct timespec *a,
 	}
 }
 
-static void perf_evlist__free_stats(struct perf_evlist *evlist)
-{
-	struct perf_evsel *evsel;
-
-	evlist__for_each(evlist, evsel) {
-		perf_evsel__free_stat_priv(evsel);
-		perf_evsel__free_counts(evsel);
-		perf_evsel__free_prev_raw_counts(evsel);
-	}
-}
-
-static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
-{
-	struct perf_evsel *evsel;
-	int nthreads = thread_map__nr(evsel_list->threads);
-
-	evlist__for_each(evlist, evsel) {
-		int ncpus = perf_evsel__nr_cpus(evsel);
-
-		if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
-		    perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
-		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
-			goto out_free;
-	}
-
-	return 0;
-
-out_free:
-	perf_evlist__free_stats(evlist);
-	return -1;
-}
-
-static void perf_evlist__reset_stats(struct perf_evlist *evlist)
-{
-	struct perf_evsel *evsel;
-
-	evlist__for_each(evlist, evsel) {
-		perf_evsel__reset_stat_priv(evsel);
-		perf_evsel__reset_counts(evsel);
-	}
-}
-
 static void perf_stat__reset_stats(void)
 {
 	perf_evlist__reset_stats(evsel_list);
tools/perf/util/evlist.h +0 -1
index a8489b9..037633c 100644
@@ -289,5 +289,4 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
 
 void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
 				     struct perf_evsel *tracking_evsel);
-
 #endif /* __PERF_EVLIST_H */
tools/perf/util/stat.c +44 -0

53 lines not on this page · raw message

tools/perf/util/stat.h +6 -0
index 454b268..5f62db2 100644
@@ -70,6 +70,8 @@ static inline void init_stats(struct stats *stats)
 }
 
 struct perf_evsel;
+struct perf_evlist;
+
 bool __perf_evsel_stat__is(struct perf_evsel *evsel,
 			   enum perf_stat_evsel_id id);
 
@@ -100,4 +102,8 @@ void perf_evsel__free_stat_priv(struct perf_evsel *evsel);
 int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
 				      int ncpus, int nthreads);
 void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel);
+
+int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw);
+void perf_evlist__free_stats(struct perf_evlist *evlist);
+void perf_evlist__reset_stats(struct perf_evlist *evlist);
 #endif
author reviewer
#24 lore raw

PATCH v5 12/22 perf stat: Introduce perf_evsel__alloc_stats function

In reply to Jiri Olsa

Move all stat allocation logic related to stat
object under single function. This way we can
use it separately for stat object out of evlist
object.

---
 tools/perf/util/stat.c | 20 ++++++++++++++------
 tools/perf/util/stat.h |  2 ++
 2 files changed, 16 insertions(+), 6 deletions(-)
tools/perf/util/stat.c +14 -6
index 818cb022fcb6..f2a0d1521e26 100644
@@ -189,17 +189,25 @@ void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
 	evsel->prev_raw_counts = NULL;
 }
 
+int perf_evsel__alloc_stats(struct perf_evsel *evsel, bool alloc_raw)
+{
+	int ncpus = perf_evsel__nr_cpus(evsel);
+	int nthreads = thread_map__nr(evsel->threads);
+
+	if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
+	    perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
+	    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
+		return -ENOMEM;
+
+	return 0;
+}
+
 int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
 {
 	struct perf_evsel *evsel;
-	int nthreads = thread_map__nr(evlist->threads);
 
 	evlist__for_each(evlist, evsel) {
-		int ncpus = perf_evsel__nr_cpus(evsel);
-
-		if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
-		    perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
-		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
+		if (perf_evsel__alloc_stats(evsel, alloc_raw))
 			goto out_free;
 	}
 
tools/perf/util/stat.h +2 -0
index 5f62db2472c7..9f05c571befe 100644
@@ -103,6 +103,8 @@ int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
 				      int ncpus, int nthreads);
 void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel);
 
+int perf_evsel__alloc_stats(struct perf_evsel *evsel, bool alloc_raw);
+
 int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw);
 void perf_evlist__free_stats(struct perf_evlist *evlist);
 void perf_evlist__reset_stats(struct perf_evlist *evlist);
Signature · 1 line
1.9.3
#25 lore raw

[tip:perf/urgent] perf stat: Introduce perf_evsel__alloc_stats function

perf stat: Introduce perf_evsel__alloc_stats function
Commit-ID:  a7d0a102e4ae46b75b70a9500979e7ed3cdf183f
Gitweb:     http://git.kernel.org/tip/a7d0a102e4ae46b75b70a9500979e7ed3cdf183f
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:17 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:46:00 -0300

perf stat: Introduce perf_evsel__alloc_stats function

Move all stat allocation logic related to stat object under single function. This way we can use it separately for stat object out of evlist object.

---
 tools/perf/util/stat.c | 20 ++++++++++++++------
 tools/perf/util/stat.h |  2 ++
 2 files changed, 16 insertions(+), 6 deletions(-)
tools/perf/util/stat.c +14 -6
index 818cb02..f2a0d15 100644
@@ -189,17 +189,25 @@ void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
 	evsel->prev_raw_counts = NULL;
 }
 
+int perf_evsel__alloc_stats(struct perf_evsel *evsel, bool alloc_raw)
+{
+	int ncpus = perf_evsel__nr_cpus(evsel);
+	int nthreads = thread_map__nr(evsel->threads);
+
+	if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
+	    perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
+	    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
+		return -ENOMEM;
+
+	return 0;
+}
+
 int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
 {
 	struct perf_evsel *evsel;
-	int nthreads = thread_map__nr(evlist->threads);
 
 	evlist__for_each(evlist, evsel) {
-		int ncpus = perf_evsel__nr_cpus(evsel);
-
-		if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
-		    perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
-		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
+		if (perf_evsel__alloc_stats(evsel, alloc_raw))
 			goto out_free;
 	}
 
tools/perf/util/stat.h +2 -0
index 5f62db2..9f05c57 100644
@@ -103,6 +103,8 @@ int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
 				      int ncpus, int nthreads);
 void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel);
 
+int perf_evsel__alloc_stats(struct perf_evsel *evsel, bool alloc_raw);
+
 int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw);
 void perf_evlist__free_stats(struct perf_evlist *evlist);
 void perf_evlist__reset_stats(struct perf_evlist *evlist);
author reviewer
#26 lore raw

PATCH v5 13/22 perf stat: Introduce perf_evsel__read function

In reply to Jiri Olsa

Adding simple read function that reads/store data into given struct perf_counts_values *count object.

---
 tools/perf/util/evsel.c | 14 ++++++++++++++
 tools/perf/util/evsel.h |  3 +++
 2 files changed, 17 insertions(+)
tools/perf/util/evsel.c +14 -0
index cd6ce7066f85..2e0a4e064f44 100644
@@ -955,6 +955,20 @@ int perf_evsel__read_cb(struct perf_evsel *evsel, int cpu, int thread,
 	return cb(evsel, cpu, thread, &count);
 }
 
+int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
+		     struct perf_counts_values *count)
+{
+	memset(count, 0, sizeof(*count));
+
+	if (FD(evsel, cpu, thread) < 0)
+		return -EINVAL;
+
+	if (readn(FD(evsel, cpu, thread), count, sizeof(*count)) < 0)
+		return -errno;
+
+	return 0;
+}
+
 int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
 			      int cpu, int thread, bool scale)
 {
tools/perf/util/evsel.h +3 -0
index 020f7e13634a..a79944a21e8f 100644
@@ -236,6 +236,9 @@ typedef int (perf_evsel__read_cb_t)(struct perf_evsel *evsel,
 int perf_evsel__read_cb(struct perf_evsel *evsel, int cpu, int thread,
 			perf_evsel__read_cb_t cb);
 
+int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
+		     struct perf_counts_values *count);
+
 int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
 			      int cpu, int thread, bool scale);
 
Signature · 1 line
1.9.3
#27 lore raw

[tip:perf/urgent] perf stat: Introduce perf_evsel__read function

perf stat: Introduce perf_evsel__read function
Commit-ID:  f99f4719b841a9745d6a7652eef3956aaf2db66a
Gitweb:     http://git.kernel.org/tip/f99f4719b841a9745d6a7652eef3956aaf2db66a
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:18 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:46:57 -0300

perf stat: Introduce perf_evsel__read function

Adding simple read function that reads/store data into given struct perf_counts_values *count object.

---
 tools/perf/util/evsel.c | 14 ++++++++++++++
 tools/perf/util/evsel.h |  3 +++
 2 files changed, 17 insertions(+)
tools/perf/util/evsel.c +14 -0
index cd6ce70..2e0a4e0 100644
@@ -955,6 +955,20 @@ int perf_evsel__read_cb(struct perf_evsel *evsel, int cpu, int thread,
 	return cb(evsel, cpu, thread, &count);
 }
 
+int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
+		     struct perf_counts_values *count)
+{
+	memset(count, 0, sizeof(*count));
+
+	if (FD(evsel, cpu, thread) < 0)
+		return -EINVAL;
+
+	if (readn(FD(evsel, cpu, thread), count, sizeof(*count)) < 0)
+		return -errno;
+
+	return 0;
+}
+
 int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
 			      int cpu, int thread, bool scale)
 {
tools/perf/util/evsel.h +3 -0
index 020f7e1..a79944a 100644
@@ -236,6 +236,9 @@ typedef int (perf_evsel__read_cb_t)(struct perf_evsel *evsel,
 int perf_evsel__read_cb(struct perf_evsel *evsel, int cpu, int thread,
 			perf_evsel__read_cb_t cb);
 
+int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
+		     struct perf_counts_values *count);
+
 int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
 			      int cpu, int thread, bool scale);
 
author reviewer
#28 lore raw

PATCH v5 14/22 perf stat: Introduce read_counters function

In reply to Jiri Olsa

Moving read counters logic into single read_counters function, which will be called for both interval and overall processing legs.

The reason is to split reading and processing (following patches) counters code, so we could read counters from other sources (like perf.data) and process them in the same way as 'perf stat' command does.

---
 tools/perf/builtin-stat.c | 47 ++++++++++++++++++++++-------------------------
 1 file changed, 22 insertions(+), 25 deletions(-)
tools/perf/builtin-stat.c +22 -25
index 3e385f9f12ee..158859e622d3 100644
@@ -323,27 +323,35 @@ static int read_counter(struct perf_evsel *counter)
 	return 0;
 }
 
-static void print_interval(void)
+static void read_counters(bool close)
 {
-	static int num_print_interval;
 	struct perf_evsel *counter;
 	struct perf_stat *ps;
-	struct timespec ts, rs;
-	char prefix[64];
 
-	if (aggr_mode == AGGR_GLOBAL) {
-		evlist__for_each(evsel_list, counter) {
-			ps = counter->priv;
-			memset(ps->res_stats, 0, sizeof(ps->res_stats));
+	evlist__for_each(evsel_list, counter) {
+		ps = counter->priv;
+		memset(ps->res_stats, 0, sizeof(ps->res_stats));
+
+		if (aggr_mode == AGGR_GLOBAL)
 			read_counter_aggr(counter);
-		}
-	} else	{
-		evlist__for_each(evsel_list, counter) {
-			ps = counter->priv;
-			memset(ps->res_stats, 0, sizeof(ps->res_stats));
+		else
 			read_counter(counter);
+
+		if (close) {
+			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
+					     thread_map__nr(evsel_list->threads));
 		}
 	}
+}
+
+static void print_interval(void)
+{
+	static int num_print_interval;
+	struct perf_evsel *counter;
+	struct timespec ts, rs;
+	char prefix[64];
+
+	read_counters(false);
 
 	clock_gettime(CLOCK_MONOTONIC, &ts);
 	diff_timespec(&rs, &ts, &ref_time);
@@ -525,18 +533,7 @@ static int __run_perf_stat(int argc, const char **argv)
 
 	update_stats(&walltime_nsecs_stats, t1 - t0);
 
-	if (aggr_mode == AGGR_GLOBAL) {
-		evlist__for_each(evsel_list, counter) {
-			read_counter_aggr(counter);
-			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
-					     thread_map__nr(evsel_list->threads));
-		}
-	} else {
-		evlist__for_each(evsel_list, counter) {
-			read_counter(counter);
-			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
-		}
-	}
+	read_counters(true);
 
 	return WEXITSTATUS(status);
 }
Signature · 1 line
1.9.3
#29 lore raw

[tip:perf/urgent] perf stat: Introduce read_counters function

perf stat: Introduce read_counters function
Commit-ID:  106a94a0f8c207ef4113ce7e32f34a00b3b174e7
Gitweb:     http://git.kernel.org/tip/106a94a0f8c207ef4113ce7e32f34a00b3b174e7
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:19 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:48:02 -0300

perf stat: Introduce read_counters function

Moving read counters logic into single read_counters function, which will be called for both interval and overall processing legs.

The reason is to split reading and processing (following patches) counters code, so we could read counters from other sources (like perf.data) and process them in the same way as 'perf stat' command does.

---
 tools/perf/builtin-stat.c | 47 ++++++++++++++++++++++-------------------------
 1 file changed, 22 insertions(+), 25 deletions(-)
tools/perf/builtin-stat.c +22 -25
index 3e385f9..158859e 100644
@@ -323,27 +323,35 @@ static int read_counter(struct perf_evsel *counter)
 	return 0;
 }
 
-static void print_interval(void)
+static void read_counters(bool close)
 {
-	static int num_print_interval;
 	struct perf_evsel *counter;
 	struct perf_stat *ps;
-	struct timespec ts, rs;
-	char prefix[64];
 
-	if (aggr_mode == AGGR_GLOBAL) {
-		evlist__for_each(evsel_list, counter) {
-			ps = counter->priv;
-			memset(ps->res_stats, 0, sizeof(ps->res_stats));
+	evlist__for_each(evsel_list, counter) {
+		ps = counter->priv;
+		memset(ps->res_stats, 0, sizeof(ps->res_stats));
+
+		if (aggr_mode == AGGR_GLOBAL)
 			read_counter_aggr(counter);
-		}
-	} else	{
-		evlist__for_each(evsel_list, counter) {
-			ps = counter->priv;
-			memset(ps->res_stats, 0, sizeof(ps->res_stats));
+		else
 			read_counter(counter);
+
+		if (close) {
+			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
+					     thread_map__nr(evsel_list->threads));
 		}
 	}
+}
+
+static void print_interval(void)
+{
+	static int num_print_interval;
+	struct perf_evsel *counter;
+	struct timespec ts, rs;
+	char prefix[64];
+
+	read_counters(false);
 
 	clock_gettime(CLOCK_MONOTONIC, &ts);
 	diff_timespec(&rs, &ts, &ref_time);
@@ -525,18 +533,7 @@ static int __run_perf_stat(int argc, const char **argv)
 
 	update_stats(&walltime_nsecs_stats, t1 - t0);
 
-	if (aggr_mode == AGGR_GLOBAL) {
-		evlist__for_each(evsel_list, counter) {
-			read_counter_aggr(counter);
-			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
-					     thread_map__nr(evsel_list->threads));
-		}
-	} else {
-		evlist__for_each(evsel_list, counter) {
-			read_counter(counter);
-			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
-		}
-	}
+	read_counters(true);
 
 	return WEXITSTATUS(status);
 }
author reviewer
#30 lore raw

PATCH v5 15/22 perf stat: Separate counters reading and processing

In reply to Jiri Olsa

Separating counters reading and processing so we could use the processing part in following patches.

Using simple reading via perf_evsel__read function to read counters now, because part of the processing was in the read_cb callback.

---
 tools/perf/builtin-stat.c | 56 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 39 insertions(+), 17 deletions(-)
tools/perf/builtin-stat.c +39 -17
index 158859e622d3..74ac92baa2bd 100644
@@ -217,8 +217,9 @@ static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
 	return 0;
 }
 
-static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
-		   struct perf_counts_values *count)
+static int
+process_counter_values(struct perf_evsel *evsel, int cpu, int thread,
+		       struct perf_counts_values *count)
 {
 	struct perf_counts_values *aggr = &evsel->counts->aggr;
 	static struct perf_counts_values zero;
@@ -239,7 +240,6 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
 		if (!evsel->snapshot)
 			perf_evsel__compute_deltas(evsel, cpu, thread, count);
 		perf_counts_values__scale(count, scale, NULL);
-		*perf_counts(evsel->counts, cpu, thread) = *count;
 		if (aggr_mode == AGGR_NONE)
 			perf_stat__update_shadow_stats(evsel, count->values, cpu);
 		break;
@@ -256,23 +256,41 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
 	return 0;
 }
 
-static int read_counter(struct perf_evsel *counter);
+static int process_counter_maps(struct perf_evsel *counter)
+{
+	int nthreads = thread_map__nr(counter->threads);
+	int ncpus = perf_evsel__nr_cpus(counter);
+	int cpu, thread;
 
-/*
- * Read out the results of a single counter:
- * aggregate counts across CPUs in system-wide mode
- */
-static int read_counter_aggr(struct perf_evsel *counter)
+	if (counter->system_wide)
+		nthreads = 1;
+
+	for (thread = 0; thread < nthreads; thread++) {
+		for (cpu = 0; cpu < ncpus; cpu++) {
+			if (process_counter_values(counter, cpu, thread,
+						   perf_counts(counter->counts, cpu, thread)))
+				return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int process_counter(struct perf_evsel *counter)
 {
 	struct perf_counts_values *aggr = &counter->counts->aggr;
 	struct perf_stat *ps = counter->priv;
 	u64 *count = counter->counts->aggr.values;
-	int i;
+	int i, ret;
 
 	aggr->val = aggr->ena = aggr->run = 0;
 
-	if (read_counter(counter))
-		return -1;
+	ret = process_counter_maps(counter);
+	if (ret)
+		return ret;
+
+	if (aggr_mode != AGGR_GLOBAL)
+		return 0;
 
 	if (!counter->snapshot)
 		perf_evsel__compute_deltas(counter, -1, -1, aggr);
@@ -315,7 +333,10 @@ static int read_counter(struct perf_evsel *counter)
 
 	for (thread = 0; thread < nthreads; thread++) {
 		for (cpu = 0; cpu < ncpus; cpu++) {
-			if (perf_evsel__read_cb(counter, cpu, thread, read_cb))
+			struct perf_counts_values *count;
+
+			count = perf_counts(counter->counts, cpu, thread);
+			if (perf_evsel__read(counter, cpu, thread, count))
 				return -1;
 		}
 	}
@@ -332,10 +353,11 @@ static void read_counters(bool close)
 		ps = counter->priv;
 		memset(ps->res_stats, 0, sizeof(ps->res_stats));
 
-		if (aggr_mode == AGGR_GLOBAL)
-			read_counter_aggr(counter);
-		else
-			read_counter(counter);
+		if (read_counter(counter))
+			pr_warning("failed to read counter %s\n", counter->name);
+
+		if (process_counter(counter))
+			pr_warning("failed to process counter %s\n", counter->name);
 
 		if (close) {
 			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
Signature · 1 line
1.9.3
#31 lore raw

[tip:perf/urgent] perf stat: Separate counters reading and processing

perf stat: Separate counters reading and processing
Commit-ID:  3b3eb044519ac4c422dbc6084303c470b8d2dc61
Gitweb:     http://git.kernel.org/tip/3b3eb044519ac4c422dbc6084303c470b8d2dc61
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:20 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:49:03 -0300

perf stat: Separate counters reading and processing

Separating counters reading and processing so we could use the processing part in following patches.

Using simple reading via perf_evsel__read function to read counters now, because part of the processing was in the read_cb callback.

---
 tools/perf/builtin-stat.c | 56 +++++++++++++++++++++++++++++++++--------------
 1 file changed, 39 insertions(+), 17 deletions(-)
tools/perf/builtin-stat.c +39 -17
index 158859e..74ac92b 100644
@@ -217,8 +217,9 @@ static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
 	return 0;
 }
 
-static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
-		   struct perf_counts_values *count)
+static int
+process_counter_values(struct perf_evsel *evsel, int cpu, int thread,
+		       struct perf_counts_values *count)
 {
 	struct perf_counts_values *aggr = &evsel->counts->aggr;
 	static struct perf_counts_values zero;
@@ -239,7 +240,6 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
 		if (!evsel->snapshot)
 			perf_evsel__compute_deltas(evsel, cpu, thread, count);
 		perf_counts_values__scale(count, scale, NULL);
-		*perf_counts(evsel->counts, cpu, thread) = *count;
 		if (aggr_mode == AGGR_NONE)
 			perf_stat__update_shadow_stats(evsel, count->values, cpu);
 		break;
@@ -256,23 +256,41 @@ static int read_cb(struct perf_evsel *evsel, int cpu, int thread,
 	return 0;
 }
 
-static int read_counter(struct perf_evsel *counter);
+static int process_counter_maps(struct perf_evsel *counter)
+{
+	int nthreads = thread_map__nr(counter->threads);
+	int ncpus = perf_evsel__nr_cpus(counter);
+	int cpu, thread;
 
-/*
- * Read out the results of a single counter:
- * aggregate counts across CPUs in system-wide mode
- */
-static int read_counter_aggr(struct perf_evsel *counter)
+	if (counter->system_wide)
+		nthreads = 1;
+
+	for (thread = 0; thread < nthreads; thread++) {
+		for (cpu = 0; cpu < ncpus; cpu++) {
+			if (process_counter_values(counter, cpu, thread,
+						   perf_counts(counter->counts, cpu, thread)))
+				return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int process_counter(struct perf_evsel *counter)
 {
 	struct perf_counts_values *aggr = &counter->counts->aggr;
 	struct perf_stat *ps = counter->priv;
 	u64 *count = counter->counts->aggr.values;
-	int i;
+	int i, ret;
 
 	aggr->val = aggr->ena = aggr->run = 0;
 
-	if (read_counter(counter))
-		return -1;
+	ret = process_counter_maps(counter);
+	if (ret)
+		return ret;
+
+	if (aggr_mode != AGGR_GLOBAL)
+		return 0;
 
 	if (!counter->snapshot)
 		perf_evsel__compute_deltas(counter, -1, -1, aggr);
@@ -315,7 +333,10 @@ static int read_counter(struct perf_evsel *counter)
 
 	for (thread = 0; thread < nthreads; thread++) {
 		for (cpu = 0; cpu < ncpus; cpu++) {
-			if (perf_evsel__read_cb(counter, cpu, thread, read_cb))
+			struct perf_counts_values *count;
+
+			count = perf_counts(counter->counts, cpu, thread);
+			if (perf_evsel__read(counter, cpu, thread, count))
 				return -1;
 		}
 	}
@@ -332,10 +353,11 @@ static void read_counters(bool close)
 		ps = counter->priv;
 		memset(ps->res_stats, 0, sizeof(ps->res_stats));
 
-		if (aggr_mode == AGGR_GLOBAL)
-			read_counter_aggr(counter);
-		else
-			read_counter(counter);
+		if (read_counter(counter))
+			pr_warning("failed to read counter %s\n", counter->name);
+
+		if (process_counter(counter))
+			pr_warning("failed to process counter %s\n", counter->name);
 
 		if (close) {
 			perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
author reviewer
#32 lore raw

PATCH v5 16/22 perf stat: Move zero_per_pkg into counter process code

In reply to Jiri Olsa

Moving zero_per_pkg into counter process code, to make the reading path free of processing logic.

---
 tools/perf/builtin-stat.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +3 -3
index 74ac92baa2bd..b7c184bd559c 100644
@@ -285,6 +285,9 @@ static int process_counter(struct perf_evsel *counter)
 
 	aggr->val = aggr->ena = aggr->run = 0;
 
+	if (counter->per_pkg)
+		zero_per_pkg(counter);
+
 	ret = process_counter_maps(counter);
 	if (ret)
 		return ret;
@@ -328,9 +331,6 @@ static int read_counter(struct perf_evsel *counter)
 	if (counter->system_wide)
 		nthreads = 1;
 
-	if (counter->per_pkg)
-		zero_per_pkg(counter);
-
 	for (thread = 0; thread < nthreads; thread++) {
 		for (cpu = 0; cpu < ncpus; cpu++) {
 			struct perf_counts_values *count;
Signature · 1 line
1.9.3
#33 lore raw

[tip:perf/urgent] perf stat: Move zero_per_pkg into counter process code

perf stat: Move zero_per_pkg into counter process code
Commit-ID:  32ce0a47aaa401a7dd27dfe65210f3e3aa809682
Gitweb:     http://git.kernel.org/tip/32ce0a47aaa401a7dd27dfe65210f3e3aa809682
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:21 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:49:45 -0300

perf stat: Move zero_per_pkg into counter process code

Moving zero_per_pkg into counter process code, to make the reading path free of processing logic.

---
 tools/perf/builtin-stat.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +3 -3
index 74ac92b..b7c184b 100644
@@ -285,6 +285,9 @@ static int process_counter(struct perf_evsel *counter)
 
 	aggr->val = aggr->ena = aggr->run = 0;
 
+	if (counter->per_pkg)
+		zero_per_pkg(counter);
+
 	ret = process_counter_maps(counter);
 	if (ret)
 		return ret;
@@ -328,9 +331,6 @@ static int read_counter(struct perf_evsel *counter)
 	if (counter->system_wide)
 		nthreads = 1;
 
-	if (counter->per_pkg)
-		zero_per_pkg(counter);
-
 	for (thread = 0; thread < nthreads; thread++) {
 		for (cpu = 0; cpu < ncpus; cpu++) {
 			struct perf_counts_values *count;
author reviewer
#34 lore raw

PATCH v5 17/22 perf stat: Move perf_stat initialization counter process code

In reply to Jiri Olsa

Moving perf_stat initialization counter process code, to make the reading path free of processing logic.

---
 tools/perf/builtin-stat.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
tools/perf/builtin-stat.c +1 -4
index b7c184bd559c..526f67753664 100644
@@ -284,6 +284,7 @@ static int process_counter(struct perf_evsel *counter)
 	int i, ret;
 
 	aggr->val = aggr->ena = aggr->run = 0;
+	memset(ps->res_stats, 0, sizeof(ps->res_stats));
 
 	if (counter->per_pkg)
 		zero_per_pkg(counter);
@@ -347,12 +348,8 @@ static int read_counter(struct perf_evsel *counter)
 static void read_counters(bool close)
 {
 	struct perf_evsel *counter;
-	struct perf_stat *ps;
 
 	evlist__for_each(evsel_list, counter) {
-		ps = counter->priv;
-		memset(ps->res_stats, 0, sizeof(ps->res_stats));
-
 		if (read_counter(counter))
 			pr_warning("failed to read counter %s\n", counter->name);
 
Signature · 1 line
1.9.3
#35 lore raw

[tip:perf/urgent] perf stat: Move perf_stat initialization counter process code

perf stat: Move perf_stat initialization counter process code
Commit-ID:  7ddb1b6bbf1e614e6700f226cb0a559c5c635336
Gitweb:     http://git.kernel.org/tip/7ddb1b6bbf1e614e6700f226cb0a559c5c635336
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:22 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:50:19 -0300

perf stat: Move perf_stat initialization counter process code

Moving perf_stat initialization counter process code, to make the reading path free of processing logic.

---
 tools/perf/builtin-stat.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)
tools/perf/builtin-stat.c +1 -4
index b7c184b..526f677 100644
@@ -284,6 +284,7 @@ static int process_counter(struct perf_evsel *counter)
 	int i, ret;
 
 	aggr->val = aggr->ena = aggr->run = 0;
+	memset(ps->res_stats, 0, sizeof(ps->res_stats));
 
 	if (counter->per_pkg)
 		zero_per_pkg(counter);
@@ -347,12 +348,8 @@ static int read_counter(struct perf_evsel *counter)
 static void read_counters(bool close)
 {
 	struct perf_evsel *counter;
-	struct perf_stat *ps;
 
 	evlist__for_each(evsel_list, counter) {
-		ps = counter->priv;
-		memset(ps->res_stats, 0, sizeof(ps->res_stats));
-
 		if (read_counter(counter))
 			pr_warning("failed to read counter %s\n", counter->name);
 
author reviewer
#36 lore raw

PATCH v5 18/22 perf stat: Remove perf_evsel__read_cb function

In reply to Jiri Olsa

It's no longer used, the stat command uses perf_evsel__read now.

---
 tools/perf/util/evsel.c | 16 ----------------
 tools/perf/util/evsel.h |  7 -------
 2 files changed, 23 deletions(-)
tools/perf/util/evsel.c +0 -16
index 2e0a4e064f44..2936b3080722 100644
@@ -939,22 +939,6 @@ void perf_counts_values__scale(struct perf_counts_values *count,
 		*pscaled = scaled;
 }
 
-int perf_evsel__read_cb(struct perf_evsel *evsel, int cpu, int thread,
-			perf_evsel__read_cb_t cb)
-{
-	struct perf_counts_values count;
-
-	memset(&count, 0, sizeof(count));
-
-	if (FD(evsel, cpu, thread) < 0)
-		return -EINVAL;
-
-	if (readn(FD(evsel, cpu, thread), &count, sizeof(count)) < 0)
-		return -errno;
-
-	return cb(evsel, cpu, thread, &count);
-}
-
 int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
 		     struct perf_counts_values *count)
 {
tools/perf/util/evsel.h +0 -7
index a79944a21e8f..4a7ed5656cf0 100644
@@ -229,13 +229,6 @@ static inline bool perf_evsel__match2(struct perf_evsel *e1,
 	 (a)->attr.type == (b)->attr.type &&	\
 	 (a)->attr.config == (b)->attr.config)
 
-typedef int (perf_evsel__read_cb_t)(struct perf_evsel *evsel,
-				    int cpu, int thread,
-				    struct perf_counts_values *count);
-
-int perf_evsel__read_cb(struct perf_evsel *evsel, int cpu, int thread,
-			perf_evsel__read_cb_t cb);
-
 int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
 		     struct perf_counts_values *count);
 
Signature · 1 line
1.9.3
#37 lore raw

[tip:perf/urgent] perf stat: Remove perf_evsel__read_cb function

perf stat: Remove perf_evsel__read_cb function
Commit-ID:  d8ee3b54d0458cbed0a31a410458f4bfd38fc147
Gitweb:     http://git.kernel.org/tip/d8ee3b54d0458cbed0a31a410458f4bfd38fc147
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:23 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:50:51 -0300

perf stat: Remove perf_evsel__read_cb function

It's no longer used, the stat command uses perf_evsel__read now.

---
 tools/perf/util/evsel.c | 16 ----------------
 tools/perf/util/evsel.h |  7 -------
 2 files changed, 23 deletions(-)
tools/perf/util/evsel.c +0 -16
index 2e0a4e0..2936b30 100644
@@ -939,22 +939,6 @@ void perf_counts_values__scale(struct perf_counts_values *count,
 		*pscaled = scaled;
 }
 
-int perf_evsel__read_cb(struct perf_evsel *evsel, int cpu, int thread,
-			perf_evsel__read_cb_t cb)
-{
-	struct perf_counts_values count;
-
-	memset(&count, 0, sizeof(count));
-
-	if (FD(evsel, cpu, thread) < 0)
-		return -EINVAL;
-
-	if (readn(FD(evsel, cpu, thread), &count, sizeof(count)) < 0)
-		return -errno;
-
-	return cb(evsel, cpu, thread, &count);
-}
-
 int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
 		     struct perf_counts_values *count)
 {
tools/perf/util/evsel.h +0 -7
index a79944a..4a7ed56 100644
@@ -229,13 +229,6 @@ static inline bool perf_evsel__match2(struct perf_evsel *e1,
 	 (a)->attr.type == (b)->attr.type &&	\
 	 (a)->attr.config == (b)->attr.config)
 
-typedef int (perf_evsel__read_cb_t)(struct perf_evsel *evsel,
-				    int cpu, int thread,
-				    struct perf_counts_values *count);
-
-int perf_evsel__read_cb(struct perf_evsel *evsel, int cpu, int thread,
-			perf_evsel__read_cb_t cb);
-
 int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
 		     struct perf_counts_values *count);
 
author reviewer
#38 lore raw

PATCH v5 19/22 perf stat: Rename print_interval to process_interval

In reply to Jiri Olsa

It suits better, because the function also reads counter's data.

Also the 'print_interval' name will be used in following generalization of counters display.

---
 tools/perf/builtin-stat.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +3 -3
index 526f67753664..aa706fca410e 100644
@@ -363,7 +363,7 @@ static void read_counters(bool close)
 	}
 }
 
-static void print_interval(void)
+static void process_interval(void)
 {
 	static int num_print_interval;
 	struct perf_evsel *counter;
@@ -526,7 +526,7 @@ static int __run_perf_stat(int argc, const char **argv)
 		if (interval) {
 			while (!waitpid(child_pid, &status, WNOHANG)) {
 				nanosleep(&ts, NULL);
-				print_interval();
+				process_interval();
 			}
 		}
 		wait(&status);
@@ -544,7 +544,7 @@ static int __run_perf_stat(int argc, const char **argv)
 		while (!done) {
 			nanosleep(&ts, NULL);
 			if (interval)
-				print_interval();
+				process_interval();
 		}
 	}
 
Signature · 1 line
1.9.3
#39 lore raw

[tip:perf/urgent] perf stat: Rename print_interval to process_interval

perf stat: Rename print_interval to process_interval
Commit-ID:  ba411a954eae3e88c02667a5670cac97fb9c3f58
Gitweb:     http://git.kernel.org/tip/ba411a954eae3e88c02667a5670cac97fb9c3f58
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:24 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:51:23 -0300

perf stat: Rename print_interval to process_interval

It suits better, because the function also reads counter's data.

Also the 'print_interval' name will be used in following generalization of counters display.

---
 tools/perf/builtin-stat.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-stat.c +3 -3
index 526f677..aa706fc 100644
@@ -363,7 +363,7 @@ static void read_counters(bool close)
 	}
 }
 
-static void print_interval(void)
+static void process_interval(void)
 {
 	static int num_print_interval;
 	struct perf_evsel *counter;
@@ -526,7 +526,7 @@ static int __run_perf_stat(int argc, const char **argv)
 		if (interval) {
 			while (!waitpid(child_pid, &status, WNOHANG)) {
 				nanosleep(&ts, NULL);
-				print_interval();
+				process_interval();
 			}
 		}
 		wait(&status);
@@ -544,7 +544,7 @@ static int __run_perf_stat(int argc, const char **argv)
 		while (!done) {
 			nanosleep(&ts, NULL);
 			if (interval)
-				print_interval();
+				process_interval();
 		}
 	}
 
author reviewer
#40 lore raw

PATCH v5 20/22 perf stat: Using init_stats instead of memset

In reply to Jiri Olsa

The init_stats function is meant to init 'struct stats'.

---
 tools/perf/builtin-stat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-stat.c +1 -1
index aa706fca410e..39a97ade2cf3 100644
@@ -284,7 +284,7 @@ static int process_counter(struct perf_evsel *counter)
 	int i, ret;
 
 	aggr->val = aggr->ena = aggr->run = 0;
-	memset(ps->res_stats, 0, sizeof(ps->res_stats));
+	init_stats(ps->res_stats);
 
 	if (counter->per_pkg)
 		zero_per_pkg(counter);
Signature · 1 line
1.9.3
#41 lore raw

[tip:perf/urgent] perf stat: Using init_stats instead of memset

perf stat: Using init_stats instead of memset
Commit-ID:  5835e2286583e4fa6c2a609446e1320e7da2b161
Gitweb:     http://git.kernel.org/tip/5835e2286583e4fa6c2a609446e1320e7da2b161
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:25 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 11:51:49 -0300

perf stat: Using init_stats instead of memset

The init_stats function is meant to init 'struct stats'.

---
 tools/perf/builtin-stat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-stat.c +1 -1
index aa706fc..39a97ade 100644
@@ -284,7 +284,7 @@ static int process_counter(struct perf_evsel *counter)
 	int i, ret;
 
 	aggr->val = aggr->ena = aggr->run = 0;
-	memset(ps->res_stats, 0, sizeof(ps->res_stats));
+	init_stats(ps->res_stats);
 
 	if (counter->per_pkg)
 		zero_per_pkg(counter);
author reviewer
#42 lore raw

PATCH v5 21/22 perf stat: Introduce print_counters function

In reply to Jiri Olsa

Centralize counters print code into single
print_counters function.

---
 tools/perf/builtin-stat.c | 127 +++++++++++++++++++++++-----------------------
 1 file changed, 64 insertions(+), 63 deletions(-)
tools/perf/builtin-stat.c +64 -63
index 39a97ade2cf3..56dc8881cb05 100644
@@ -67,10 +67,7 @@
 #define CNTR_NOT_SUPPORTED	"<not supported>"
 #define CNTR_NOT_COUNTED	"<not counted>"
 
-static void print_stat(int argc, const char **argv);
-static void print_counter_aggr(struct perf_evsel *counter, char *prefix);
-static void print_counter(struct perf_evsel *counter, char *prefix);
-static void print_aggr(char *prefix);
+static void print_counters(struct timespec *ts, int argc, const char **argv);
 
 /* Default events used for perf stat -T */
 static const char *transaction_attrs = {
@@ -365,53 +362,14 @@ static void read_counters(bool close)
 
 static void process_interval(void)
 {
-	static int num_print_interval;
-	struct perf_evsel *counter;
 	struct timespec ts, rs;
-	char prefix[64];
 
 	read_counters(false);
 
 	clock_gettime(CLOCK_MONOTONIC, &ts);
 	diff_timespec(&rs, &ts, &ref_time);
-	sprintf(prefix, "%6lu.%09lu%s", rs.tv_sec, rs.tv_nsec, csv_sep);
-
-	if (num_print_interval == 0 && !csv_output) {
-		switch (aggr_mode) {
-		case AGGR_SOCKET:
-			fprintf(output, "#           time socket cpus             counts %*s events\n", unit_width, "unit");
-			break;
-		case AGGR_CORE:
-			fprintf(output, "#           time core         cpus             counts %*s events\n", unit_width, "unit");
-			break;
-		case AGGR_NONE:
-			fprintf(output, "#           time CPU                counts %*s events\n", unit_width, "unit");
-			break;
-		case AGGR_GLOBAL:
-		default:
-			fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
-		}
-	}
-
-	if (++num_print_interval == 25)
-		num_print_interval = 0;
 
-	switch (aggr_mode) {
-	case AGGR_CORE:
-	case AGGR_SOCKET:
-		print_aggr(prefix);
-		break;
-	case AGGR_NONE:
-		evlist__for_each(evsel_list, counter)
-			print_counter(counter, prefix);
-		break;
-	case AGGR_GLOBAL:
-	default:
-		evlist__for_each(evsel_list, counter)
-			print_counter_aggr(counter, prefix);
-	}
-
-	fflush(output);
+	print_counters(&rs, 0, NULL);
 }
 
 static void handle_initial_delay(void)
@@ -901,9 +859,35 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
 	}
 }
 
-static void print_stat(int argc, const char **argv)
+static void print_interval(char *prefix, struct timespec *ts)
+{
+	static int num_print_interval;
+
+	sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep);
+
+	if (num_print_interval == 0 && !csv_output) {
+		switch (aggr_mode) {
+		case AGGR_SOCKET:
+			fprintf(output, "#           time socket cpus             counts %*s events\n", unit_width, "unit");
+			break;
+		case AGGR_CORE:
+			fprintf(output, "#           time core         cpus             counts %*s events\n", unit_width, "unit");
+			break;
+		case AGGR_NONE:
+			fprintf(output, "#           time CPU                counts %*s events\n", unit_width, "unit");
+			break;
+		case AGGR_GLOBAL:
+		default:
+			fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
+		}
+	}
+
+	if (++num_print_interval == 25)
+		num_print_interval = 0;
+}
+
+static void print_header(int argc, const char **argv)
 {
-	struct perf_evsel *counter;
 	int i;
 
 	fflush(stdout);
@@ -929,36 +913,53 @@ static void print_stat(int argc, const char **argv)
 			fprintf(output, " (%d runs)", run_count);
 		fprintf(output, ":\n\n");
 	}
+}
+
+static void print_footer(void)
+{
+	if (!null_run)
+		fprintf(output, "\n");
+	fprintf(output, " %17.9f seconds time elapsed",
+			avg_stats(&walltime_nsecs_stats)/1e9);
+	if (run_count > 1) {
+		fprintf(output, "                                        ");
+		print_noise_pct(stddev_stats(&walltime_nsecs_stats),
+				avg_stats(&walltime_nsecs_stats));
+	}
+	fprintf(output, "\n\n");
+}
+
+static void print_counters(struct timespec *ts, int argc, const char **argv)
+{
+	struct perf_evsel *counter;
+	char buf[64], *prefix = NULL;
+
+	if (interval)
+		print_interval(prefix = buf, ts);
+	else
+		print_header(argc, argv);
 
 	switch (aggr_mode) {
 	case AGGR_CORE:
 	case AGGR_SOCKET:
-		print_aggr(NULL);
+		print_aggr(prefix);
 		break;
 	case AGGR_GLOBAL:
 		evlist__for_each(evsel_list, counter)
-			print_counter_aggr(counter, NULL);
+			print_counter_aggr(counter, prefix);
 		break;
 	case AGGR_NONE:
 		evlist__for_each(evsel_list, counter)
-			print_counter(counter, NULL);
+			print_counter(counter, prefix);
 		break;
 	default:
 		break;
 	}
 
-	if (!csv_output) {
-		if (!null_run)
-			fprintf(output, "\n");
-		fprintf(output, " %17.9f seconds time elapsed",
-				avg_stats(&walltime_nsecs_stats)/1e9);
-		if (run_count > 1) {
-			fprintf(output, "                                        ");
-			print_noise_pct(stddev_stats(&walltime_nsecs_stats),
-					avg_stats(&walltime_nsecs_stats));
-		}
-		fprintf(output, "\n\n");
-	}
+	if (!interval && !csv_output)
+		print_footer();
+
+	fflush(output);
 }
 
 static volatile int signr = -1;
@@ -1407,13 +1408,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 
 		status = run_perf_stat(argc, argv);
 		if (forever && status != -1) {
-			print_stat(argc, argv);
+			print_counters(NULL, argc, argv);
 			perf_stat__reset_stats();
 		}
 	}
 
 	if (!forever && status != -1 && !interval)
-		print_stat(argc, argv);
+		print_counters(NULL, argc, argv);
 
 	perf_evlist__free_stats(evsel_list);
 out:
Signature · 1 line
1.9.3
#43 lore raw

[tip:perf/urgent] perf stat: Introduce print_counters function

perf stat: Introduce print_counters function
Commit-ID:  d4f63a4741a808c0bf25d92884713008706fca16
Gitweb:     http://git.kernel.org/tip/d4f63a4741a808c0bf25d92884713008706fca16
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:26 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 12:00:50 -0300

perf stat: Introduce print_counters function

Centralize counters print code into single print_counters function.

---
 tools/perf/builtin-stat.c | 127 +++++++++++++++++++++++-----------------------
 1 file changed, 64 insertions(+), 63 deletions(-)
tools/perf/builtin-stat.c +64 -63
index 39a97ade..56dc888 100644
@@ -67,10 +67,7 @@
 #define CNTR_NOT_SUPPORTED	"<not supported>"
 #define CNTR_NOT_COUNTED	"<not counted>"
 
-static void print_stat(int argc, const char **argv);
-static void print_counter_aggr(struct perf_evsel *counter, char *prefix);
-static void print_counter(struct perf_evsel *counter, char *prefix);
-static void print_aggr(char *prefix);
+static void print_counters(struct timespec *ts, int argc, const char **argv);
 
 /* Default events used for perf stat -T */
 static const char *transaction_attrs = {
@@ -365,53 +362,14 @@ static void read_counters(bool close)
 
 static void process_interval(void)
 {
-	static int num_print_interval;
-	struct perf_evsel *counter;
 	struct timespec ts, rs;
-	char prefix[64];
 
 	read_counters(false);
 
 	clock_gettime(CLOCK_MONOTONIC, &ts);
 	diff_timespec(&rs, &ts, &ref_time);
-	sprintf(prefix, "%6lu.%09lu%s", rs.tv_sec, rs.tv_nsec, csv_sep);
-
-	if (num_print_interval == 0 && !csv_output) {
-		switch (aggr_mode) {
-		case AGGR_SOCKET:
-			fprintf(output, "#           time socket cpus             counts %*s events\n", unit_width, "unit");
-			break;
-		case AGGR_CORE:
-			fprintf(output, "#           time core         cpus             counts %*s events\n", unit_width, "unit");
-			break;
-		case AGGR_NONE:
-			fprintf(output, "#           time CPU                counts %*s events\n", unit_width, "unit");
-			break;
-		case AGGR_GLOBAL:
-		default:
-			fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
-		}
-	}
-
-	if (++num_print_interval == 25)
-		num_print_interval = 0;
 
-	switch (aggr_mode) {
-	case AGGR_CORE:
-	case AGGR_SOCKET:
-		print_aggr(prefix);
-		break;
-	case AGGR_NONE:
-		evlist__for_each(evsel_list, counter)
-			print_counter(counter, prefix);
-		break;
-	case AGGR_GLOBAL:
-	default:
-		evlist__for_each(evsel_list, counter)
-			print_counter_aggr(counter, prefix);
-	}
-
-	fflush(output);
+	print_counters(&rs, 0, NULL);
 }
 
 static void handle_initial_delay(void)
@@ -901,9 +859,35 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
 	}
 }
 
-static void print_stat(int argc, const char **argv)
+static void print_interval(char *prefix, struct timespec *ts)
+{
+	static int num_print_interval;
+
+	sprintf(prefix, "%6lu.%09lu%s", ts->tv_sec, ts->tv_nsec, csv_sep);
+
+	if (num_print_interval == 0 && !csv_output) {
+		switch (aggr_mode) {
+		case AGGR_SOCKET:
+			fprintf(output, "#           time socket cpus             counts %*s events\n", unit_width, "unit");
+			break;
+		case AGGR_CORE:
+			fprintf(output, "#           time core         cpus             counts %*s events\n", unit_width, "unit");
+			break;
+		case AGGR_NONE:
+			fprintf(output, "#           time CPU                counts %*s events\n", unit_width, "unit");
+			break;
+		case AGGR_GLOBAL:
+		default:
+			fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
+		}
+	}
+
+	if (++num_print_interval == 25)
+		num_print_interval = 0;
+}
+
+static void print_header(int argc, const char **argv)
 {
-	struct perf_evsel *counter;
 	int i;
 
 	fflush(stdout);
@@ -929,36 +913,53 @@ static void print_stat(int argc, const char **argv)
 			fprintf(output, " (%d runs)", run_count);
 		fprintf(output, ":\n\n");
 	}
+}
+
+static void print_footer(void)
+{
+	if (!null_run)
+		fprintf(output, "\n");
+	fprintf(output, " %17.9f seconds time elapsed",
+			avg_stats(&walltime_nsecs_stats)/1e9);
+	if (run_count > 1) {
+		fprintf(output, "                                        ");
+		print_noise_pct(stddev_stats(&walltime_nsecs_stats),
+				avg_stats(&walltime_nsecs_stats));
+	}
+	fprintf(output, "\n\n");
+}
+
+static void print_counters(struct timespec *ts, int argc, const char **argv)
+{
+	struct perf_evsel *counter;
+	char buf[64], *prefix = NULL;
+
+	if (interval)
+		print_interval(prefix = buf, ts);
+	else
+		print_header(argc, argv);
 
 	switch (aggr_mode) {
 	case AGGR_CORE:
 	case AGGR_SOCKET:
-		print_aggr(NULL);
+		print_aggr(prefix);
 		break;
 	case AGGR_GLOBAL:
 		evlist__for_each(evsel_list, counter)
-			print_counter_aggr(counter, NULL);
+			print_counter_aggr(counter, prefix);
 		break;
 	case AGGR_NONE:
 		evlist__for_each(evsel_list, counter)
-			print_counter(counter, NULL);
+			print_counter(counter, prefix);
 		break;
 	default:
 		break;
 	}
 
-	if (!csv_output) {
-		if (!null_run)
-			fprintf(output, "\n");
-		fprintf(output, " %17.9f seconds time elapsed",
-				avg_stats(&walltime_nsecs_stats)/1e9);
-		if (run_count > 1) {
-			fprintf(output, "                                        ");
-			print_noise_pct(stddev_stats(&walltime_nsecs_stats),
-					avg_stats(&walltime_nsecs_stats));
-		}
-		fprintf(output, "\n\n");
-	}
+	if (!interval && !csv_output)
+		print_footer();
+
+	fflush(output);
 }
 
 static volatile int signr = -1;
@@ -1407,13 +1408,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 
 		status = run_perf_stat(argc, argv);
 		if (forever && status != -1) {
-			print_stat(argc, argv);
+			print_counters(NULL, argc, argv);
 			perf_stat__reset_stats();
 		}
 	}
 
 	if (!forever && status != -1 && !interval)
-		print_stat(argc, argv);
+		print_counters(NULL, argc, argv);
 
 	perf_evlist__free_stats(evsel_list);
 out:
author reviewer
#44 lore raw

PATCH v5 22/22 perf stat: Introduce --per-thread option

In reply to Jiri Olsa

Currently all the -p option PID arguments tasks values get aggregated and printed as single values.

Adding --per-tasks option to print values per task.

  $ perf stat  -e cycles,instructions --per-thread -p 30190,30242
  ^C
   Performance counter stats for process id '30190,30242':
               cat-30190                     0      cycles
               yes-30242         3,842,525,421      cycles
               cat-30190                     0      instructions
               yes-30242        10,370,817,010      instructions
         1.143155657 seconds time elapsed

Also works under interval mode:

  $ perf stat  -e cycles,instructions --per-thread -p 30190,30242 -I 1000
  #           time             comm-pid                  counts unit events
       1.000073435              cat-30190                89,058      cycles
       1.000073435              yes-30242         3,360,786,902      cycles                     (100.00%)
       1.000073435              cat-30190                14,066      instructions
       1.000073435              yes-30242         9,069,937,462      instructions
       2.000204830              cat-30190                     0      cycles
       2.000204830              yes-30242         3,351,667,626      cycles
       2.000204830              cat-30190                     0      instructions
       2.000204830              yes-30242         9,045,796,885      instructions
  ^C     2.771286639              cat-30190                     0      cycles
       2.771286639              yes-30242         2,593,884,166      cycles
       2.771286639              cat-30190                     0      instructions
       2.771286639              yes-30242         7,001,171,191      instructions

It works only with -t and -p options, otherwise following error is printed:

  $ perf stat  -e cycles --per-thread  -I 1000 ls
  The --per-thread option is only available when monitoring via -p -t options.
      -p, --pid <pid>       stat events on existing process id
      -t, --tid <tid>       stat events on existing thread id
---
 tools/perf/Documentation/perf-stat.txt |  4 ++
 tools/perf/builtin-stat.c              | 76 +++++++++++++++++++++++++++++++++-
 tools/perf/util/stat.h                 |  1 +
 3 files changed, 79 insertions(+), 2 deletions(-)
tools/perf/Documentation/perf-stat.txt +4 -0
index 04e150d83e7d..47469abdcc1c 100644
@@ -144,6 +144,10 @@ is a useful mode to detect imbalance between physical cores.  To enable this mod
 use --per-core in addition to -a. (system-wide).  The output includes the
 core number and the number of online logical processors on that physical processor.
 
+--per-thread::
+Aggregate counts per monitored threads, when monitoring threads (-t option)
+or processes (-p option).
+
 -D msecs::
 --delay msecs::
 After starting the program, wait msecs before measuring. This is useful to
tools/perf/builtin-stat.c +74 -2

130 lines not on this page · raw message

tools/perf/util/stat.h +1 -0
index 9f05c571befe..1cfbe0a980ac 100644
@@ -30,6 +30,7 @@ enum aggr_mode {
 	AGGR_GLOBAL,
 	AGGR_SOCKET,
 	AGGR_CORE,
+	AGGR_THREAD,
 };
 
 struct perf_counts_values {
Signature · 1 line
1.9.3
#45 lore raw
perf stat: Introduce --per-thread option
Commit-ID:  32b8af82e3708bc19af75c31fa773a98449f0edc
Gitweb:     http://git.kernel.org/tip/32b8af82e3708bc19af75c31fa773a98449f0edc
Author:     Jiri Olsa <[email protected]>
AuthorDate: Fri, 26 Jun 2015 11:29:27 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Fri, 26 Jun 2015 12:05:04 -0300

perf stat: Introduce --per-thread option

Currently all the -p option PID arguments tasks values get aggregated and printed as single values.

Adding --per-tasks option to print values per task.

  $ perf stat  -e cycles,instructions --per-thread -p 30190,30242
  ^C
   Performance counter stats for process id '30190,30242':
               cat-30190                     0      cycles
               yes-30242         3,842,525,421      cycles
               cat-30190                     0      instructions
               yes-30242        10,370,817,010      instructions
         1.143155657 seconds time elapsed

Also works under interval mode:

  $ perf stat  -e cycles,instructions --per-thread -p 30190,30242 -I 1000
  #           time             comm-pid                  counts unit events
       1.000073435              cat-30190                89,058      cycles
       1.000073435              yes-30242         3,360,786,902      cycles                     (100.00%)
       1.000073435              cat-30190                14,066      instructions
       1.000073435              yes-30242         9,069,937,462      instructions
       2.000204830              cat-30190                     0      cycles
       2.000204830              yes-30242         3,351,667,626      cycles
       2.000204830              cat-30190                     0      instructions
       2.000204830              yes-30242         9,045,796,885      instructions
  ^C     2.771286639              cat-30190                     0      cycles
       2.771286639              yes-30242         2,593,884,166      cycles
       2.771286639              cat-30190                     0      instructions
       2.771286639              yes-30242         7,001,171,191      instructions

It works only with -t and -p options, otherwise following error is printed:

  $ perf stat  -e cycles --per-thread  -I 1000 ls
  The --per-thread option is only available when monitoring via -p -t options.
      -p, --pid <pid>       stat events on existing process id
      -t, --tid <tid>       stat events on existing thread id
---
 tools/perf/Documentation/perf-stat.txt |  4 ++
 tools/perf/builtin-stat.c              | 76 +++++++++++++++++++++++++++++++++-
 tools/perf/util/stat.h                 |  1 +
 3 files changed, 79 insertions(+), 2 deletions(-)
tools/perf/Documentation/perf-stat.txt +4 -0
index 04e150d..47469ab 100644
@@ -144,6 +144,10 @@ is a useful mode to detect imbalance between physical cores.  To enable this mod
 use --per-core in addition to -a. (system-wide).  The output includes the
 core number and the number of online logical processors on that physical processor.
 
+--per-thread::
+Aggregate counts per monitored threads, when monitoring threads (-t option)
+or processes (-p option).
+
 -D msecs::
 --delay msecs::
 After starting the program, wait msecs before measuring. This is useful to
tools/perf/builtin-stat.c +74 -2

130 lines not on this page · raw message

tools/perf/util/stat.h +1 -0
index 9f05c57..1cfbe0a 100644
@@ -30,6 +30,7 @@ enum aggr_mode {
 	AGGR_GLOBAL,
 	AGGR_SOCKET,
 	AGGR_CORE,
+	AGGR_THREAD,
 };
 
 struct perf_counts_values {
#46 lore raw
In reply to Jiri Olsa

Em Fri, Jun 26, 2015 at 11:29:05AM +0200, Jiri Olsa escreveu:

Quoted 14 lines

hi,
adding the possibility to display stat data per thread.

Allowing following commands and output:

  $ perf stat  -e cycles,instructions --per-thread -p 30190,30242
  ^C
   Performance counter stats for process id '30190,30242':
               cat-30190                     0      cycles
               yes-30242         3,842,525,421      cycles
               cat-30190                     0      instructions
               yes-30242        10,370,817,010      instructions
Quoted 7 lines
         1.143155657 seconds time elapsed

Also works under interval mode:

  $ perf stat  -e cycles,instructions --per-thread -p 30190,30242 -I 1000
  #           time             comm-pid                  counts unit events

Thanks, applied, tested,

- Arnaldo