All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC/PATCH 00/25] perf stat: Introduce --per-task option
@ 2015-06-10 18:10 Jiri Olsa
  2015-06-10 18:10 ` [PATCH 01/25] perf tools: Fix python code with missing stat dependency Jiri Olsa
                   ` (25 more replies)
  0 siblings, 26 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

hi,
adding the possibility to display stat data per thread.
Allowing following commands and output:

  $ perf stat -e cycles,instructions --per-task -p 12451,16173
  ^C
   Performance counter stats for process id '12451,16173':

  TASK-12451                77,784      cycles
  TASK-16173                64,809      cycles
  TASK-12451                14,432      instructions
  TASK-16173                14,452      instructions

         3.854957122 seconds time elapsed

Also woks under interval mode:

  $ ./perf stat -e cycles,instructions --per-task -p 16431,16173 -I 1000
  #           time task                      counts unit events
       1.000085816 TASK-16173                     0      cycles
       1.000085816 TASK-16431         3,358,360,926      cycles
       1.000085816 TASK-16173                     0      instructions
       1.000085816 TASK-16431         9,062,422,086      instructions
       2.000212262 TASK-16173                65,386      cycles
       2.000212262 TASK-16431         3,349,355,309      cycles
       2.000212262 TASK-16173                12,151      instructions
       2.000212262 TASK-16431         9,039,401,422      instructions
       3.000333402 TASK-16173                62,797      cycles
       3.000333402 TASK-16431         3,357,140,183      cycles
       3.000333402 TASK-16173                12,208      instructions
       3.000333402 TASK-16431         9,058,080,762      instructions
  ^C     3.375949851 TASK-16173                     0      cycles
       3.375949851 TASK-16431         1,264,764,804      cycles
       3.375949851 TASK-16173                     0      instructions
       3.375949851 TASK-16431         3,414,532,317      instructions

thanks for comments,
jirka


---
Jiri Olsa (25):
      perf tools: Fix python code with missing stat dependency
      perf tools: Introduce xyarray__zero function
      perf tools: Add reference counting for cpu_map object
      perf tools: Add reference counting for thread_map object
      perf tools: Propagate cpu maps through the evlist
      perf tools: Propagate thread maps through the evlist
      perf tools: Make perf_evsel__(nr_)cpus generic
      perf stat: Introduce perf_counts__(alloc|free|reset) functions
      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: Move perf_evsel__(alloc|free|reset)_stat_priv into evsel object
      perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts into evsel object
      perf stat: Move perf_evlist__(alloc|free)_stats into evlist 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: Introduce print_counters function
      perf stat: Introduce --per-task option

 tools/perf/builtin-stat.c                  | 388 +++++++++++++++++++++++++++++--------------------------------
 tools/perf/tests/code-reading.c            |   4 +-
 tools/perf/tests/keep-tracking.c           |   4 +-
 tools/perf/tests/mmap-basic.c              |   4 +-
 tools/perf/tests/mmap-thread-lookup.c      |   2 +-
 tools/perf/tests/openat-syscall-all-cpus.c |   8 +-
 tools/perf/tests/openat-syscall.c          |   6 +-
 tools/perf/tests/switch-tracking.c         |   4 +-
 tools/perf/util/cpumap.c                   |  24 +++-
 tools/perf/util/cpumap.h                   |   5 +-
 tools/perf/util/evlist.c                   |  61 +++++++++-
 tools/perf/util/evlist.h                   |   2 +
 tools/perf/util/evsel.c                    | 128 ++++++++++++++++----
 tools/perf/util/evsel.h                    |  48 ++++++--
 tools/perf/util/parse-events.c             |   5 +-
 tools/perf/util/python-ext-sources         |   1 +
 tools/perf/util/python.c                   |   4 +-
 tools/perf/util/record.c                   |   4 +-
 tools/perf/util/session.c                  |   2 +-
 tools/perf/util/stat.h                     |   1 +
 tools/perf/util/svghelper.c                |   2 +-
 tools/perf/util/thread_map.c               |  28 ++++-
 tools/perf/util/thread_map.h               |   6 +-
 tools/perf/util/xyarray.c                  |   8 ++
 tools/perf/util/xyarray.h                  |   2 +
 25 files changed, 484 insertions(+), 267 deletions(-)

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH 01/25] perf tools: Fix python code with missing stat dependency
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:55   ` Arnaldo Carvalho de Melo
  2015-06-10 18:10 ` [PATCH 02/25] perf tools: Introduce xyarray__zero function Jiri Olsa
                   ` (24 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

The evsel object now depends on stat object and breaks
python code because of missing stat object dependency.
Putting stat.c object into python object list.

Link: http://lkml.kernel.org/n/tip-o2cnaarx0buid9rtmtk5oorp@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/python-ext-sources | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index 4d28624a1eca..04fb68fc6def 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -18,4 +18,5 @@ util/cgroup.c
 util/rblist.c
 util/strlist.c
 util/trace-event.c
+util/stat.c
 ../../lib/rbtree.c
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 02/25] perf tools: Introduce xyarray__zero function
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
  2015-06-10 18:10 ` [PATCH 01/25] perf tools: Fix python code with missing stat dependency Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 19:06   ` Arnaldo Carvalho de Melo
  2015-06-10 18:10 ` [PATCH 03/25] perf tools: Add reference counting for cpu_map object Jiri Olsa
                   ` (23 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

To zero all the xyarray contents. It will be used
in following patches.

Link: http://lkml.kernel.org/n/tip-bp8bcl46cav05xn0uacg7ytn@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/xyarray.c | 8 ++++++++
 tools/perf/util/xyarray.h | 2 ++
 2 files changed, 10 insertions(+)

diff --git a/tools/perf/util/xyarray.c b/tools/perf/util/xyarray.c
index 22afbf6c536a..d0ca9ed5e7f2 100644
--- a/tools/perf/util/xyarray.c
+++ b/tools/perf/util/xyarray.c
@@ -9,11 +9,19 @@ struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size)
 	if (xy != NULL) {
 		xy->entry_size = entry_size;
 		xy->row_size   = row_size;
+		xy->entries    = xlen * ylen;
 	}
 
 	return xy;
 }
 
+void xyarray__zero(struct xyarray *xy)
+{
+	size_t n = xy->entries * xy->entry_size;
+
+	memset(xy->contents, 0, n);
+}
+
 void xyarray__delete(struct xyarray *xy)
 {
 	free(xy);
diff --git a/tools/perf/util/xyarray.h b/tools/perf/util/xyarray.h
index c488a07275dd..60cd80acdaa9 100644
--- a/tools/perf/util/xyarray.h
+++ b/tools/perf/util/xyarray.h
@@ -6,11 +6,13 @@
 struct xyarray {
 	size_t row_size;
 	size_t entry_size;
+	size_t entries;
 	char contents[];
 };
 
 struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size);
 void xyarray__delete(struct xyarray *xy);
+void xyarray__zero(struct xyarray *xy);
 
 static inline void *xyarray__entry(struct xyarray *xy, int x, int y)
 {
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 03/25] perf tools: Add reference counting for cpu_map object
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
  2015-06-10 18:10 ` [PATCH 01/25] perf tools: Fix python code with missing stat dependency Jiri Olsa
  2015-06-10 18:10 ` [PATCH 02/25] perf tools: Introduce xyarray__zero function Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 19:07   ` Arnaldo Carvalho de Melo
  2015-06-10 18:10 ` [PATCH 04/25] perf tools: Add reference counting for thread_map object Jiri Olsa
                   ` (22 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Adding refference counting for cpu_map object, so
it could be easily shared among other objects.

Using cpu_map__put instead cpu_map__delete and making
cpu_map__delete static.

Link: http://lkml.kernel.org/n/tip-gwy96ohuwhjz603bnf70af6i@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/tests/code-reading.c    |  2 +-
 tools/perf/tests/keep-tracking.c   |  2 +-
 tools/perf/tests/mmap-basic.c      |  2 +-
 tools/perf/tests/switch-tracking.c |  2 +-
 tools/perf/util/cpumap.c           | 24 ++++++++++++++++++++++--
 tools/perf/util/cpumap.h           |  5 ++++-
 tools/perf/util/evlist.c           |  4 ++--
 tools/perf/util/evsel.c            |  1 +
 tools/perf/util/parse-events.c     |  5 ++++-
 tools/perf/util/python.c           |  2 +-
 tools/perf/util/record.c           |  4 ++--
 tools/perf/util/session.c          |  2 +-
 tools/perf/util/svghelper.c        |  2 +-
 13 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index e2a432b67d52..86d17d2e9e50 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -545,7 +545,7 @@ out_err:
 	if (evlist) {
 		perf_evlist__delete(evlist);
 	} else {
-		cpu_map__delete(cpus);
+		cpu_map__put(cpus);
 		thread_map__delete(threads);
 	}
 	machines__destroy_kernel_maps(&machines);
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index 5b171d1e338b..a330235cefc0 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -144,7 +144,7 @@ out_err:
 		perf_evlist__disable(evlist);
 		perf_evlist__delete(evlist);
 	} else {
-		cpu_map__delete(cpus);
+		cpu_map__put(cpus);
 		thread_map__delete(threads);
 	}
 
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 5855cf471210..5a9ef5833452 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -140,7 +140,7 @@ out_delete_evlist:
 	cpus	= NULL;
 	threads = NULL;
 out_free_cpus:
-	cpu_map__delete(cpus);
+	cpu_map__put(cpus);
 out_free_threads:
 	thread_map__delete(threads);
 	return err;
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
index 0d31403ea593..1b06122beb76 100644
--- a/tools/perf/tests/switch-tracking.c
+++ b/tools/perf/tests/switch-tracking.c
@@ -560,7 +560,7 @@ out:
 		perf_evlist__disable(evlist);
 		perf_evlist__delete(evlist);
 	} else {
-		cpu_map__delete(cpus);
+		cpu_map__put(cpus);
 		thread_map__delete(threads);
 	}
 
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index c4e55b71010c..60f4297ed233 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -5,6 +5,7 @@
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include "asm/bug.h"
 
 static struct cpu_map *cpu_map__default_new(void)
 {
@@ -22,6 +23,7 @@ static struct cpu_map *cpu_map__default_new(void)
 			cpus->map[i] = i;
 
 		cpus->nr = nr_cpus;
+		cpus->refcnt = 1;
 	}
 
 	return cpus;
@@ -35,6 +37,7 @@ static struct cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus)
 	if (cpus != NULL) {
 		cpus->nr = nr_cpus;
 		memcpy(cpus->map, tmp_cpus, payload_size);
+		cpus->refcnt = 1;
 	}
 
 	return cpus;
@@ -194,14 +197,30 @@ struct cpu_map *cpu_map__dummy_new(void)
 	if (cpus != NULL) {
 		cpus->nr = 1;
 		cpus->map[0] = -1;
+		cpus->refcnt = 1;
 	}
 
 	return cpus;
 }
 
-void cpu_map__delete(struct cpu_map *map)
+static void cpu_map__delete(struct cpu_map *map)
 {
-	free(map);
+	if (map) {
+		WARN_ONCE(map->refcnt != 0, "cpu map refcnt disbalanced\n");
+		free(map);
+	}
+}
+
+struct cpu_map *cpu_map__get(struct cpu_map *map)
+{
+	map->refcnt++;
+	return map;
+}
+
+void cpu_map__put(struct cpu_map *map)
+{
+	if (map && --map->refcnt == 0)
+		cpu_map__delete(map);
 }
 
 int cpu_map__get_socket(struct cpu_map *map, int idx)
@@ -263,6 +282,7 @@ static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
 	/* ensure we process id in increasing order */
 	qsort(c->map, c->nr, sizeof(int), cmp_ids);
 
+	c->refcnt = 1;
 	*res = c;
 	return 0;
 }
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 61a654849002..19fe50b29375 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -8,13 +8,13 @@
 #include "util/debug.h"
 
 struct cpu_map {
+	int refcnt;
 	int nr;
 	int map[];
 };
 
 struct cpu_map *cpu_map__new(const char *cpu_list);
 struct cpu_map *cpu_map__dummy_new(void);
-void cpu_map__delete(struct cpu_map *map);
 struct cpu_map *cpu_map__read(FILE *file);
 size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp);
 int cpu_map__get_socket(struct cpu_map *map, int idx);
@@ -22,6 +22,9 @@ int cpu_map__get_core(struct cpu_map *map, int idx);
 int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp);
 int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep);
 
+struct cpu_map *cpu_map__get(struct cpu_map *map);
+void cpu_map__put(struct cpu_map *map);
+
 static inline int cpu_map__socket(struct cpu_map *sock, int s)
 {
 	if (!sock || s > sock->nr || s < 0)
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index dc1dc2c181ef..6b895de1144d 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -114,7 +114,7 @@ void perf_evlist__delete(struct perf_evlist *evlist)
 {
 	perf_evlist__munmap(evlist);
 	perf_evlist__close(evlist);
-	cpu_map__delete(evlist->cpus);
+	cpu_map__put(evlist->cpus);
 	thread_map__delete(evlist->threads);
 	evlist->cpus = NULL;
 	evlist->threads = NULL;
@@ -1337,7 +1337,7 @@ static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist)
 out:
 	return err;
 out_free_cpus:
-	cpu_map__delete(evlist->cpus);
+	cpu_map__put(evlist->cpus);
 	evlist->cpus = NULL;
 	goto out;
 }
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index a3e36fc634dc..3bd5769dd7b9 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -902,6 +902,7 @@ void perf_evsel__exit(struct perf_evsel *evsel)
 	perf_evsel__free_fd(evsel);
 	perf_evsel__free_id(evsel);
 	close_cgroup(evsel->cgrp);
+	cpu_map__put(evsel->cpus);
 	zfree(&evsel->group_name);
 	zfree(&evsel->name);
 	perf_evsel__object.fini(evsel);
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 2a4d1ec02846..09f8d2357108 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -17,6 +17,7 @@
 #include "parse-events-flex.h"
 #include "pmu.h"
 #include "thread_map.h"
+#include "cpumap.h"
 #include "asm/bug.h"
 
 #define MAX_NAME_LEN 100
@@ -285,7 +286,9 @@ __add_event(struct list_head *list, int *idx,
 	if (!evsel)
 		return NULL;
 
-	evsel->cpus = cpus;
+	if (cpus)
+		evsel->cpus = cpu_map__get(cpus);
+
 	if (name)
 		evsel->name = strdup(name);
 	list_add_tail(&evsel->node, list);
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index d906d0ad5d40..b106d56df240 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -384,7 +384,7 @@ static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
 
 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
 {
-	cpu_map__delete(pcpus->cpus);
+	cpu_map__put(pcpus->cpus);
 	pcpus->ob_type->tp_free((PyObject*)pcpus);
 }
 
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index d457c523a33d..1f7becbe5e18 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -64,7 +64,7 @@ static bool perf_probe_api(setup_probe_fn_t fn)
 	if (!cpus)
 		return false;
 	cpu = cpus->map[0];
-	cpu_map__delete(cpus);
+	cpu_map__put(cpus);
 
 	do {
 		ret = perf_do_probe_api(fn, cpu, try[i++]);
@@ -226,7 +226,7 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
 		struct cpu_map *cpus = cpu_map__new(NULL);
 
 		cpu =  cpus ? cpus->map[0] : 0;
-		cpu_map__delete(cpus);
+		cpu_map__put(cpus);
 	} else {
 		cpu = evlist->cpus->map[0];
 	}
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 88d87bf3049f..c09f178cea63 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -1838,7 +1838,7 @@ int perf_session__cpu_bitmap(struct perf_session *session,
 	err = 0;
 
 out_delete_map:
-	cpu_map__delete(map);
+	cpu_map__put(map);
 	return err;
 }
 
diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
index 283d3e73e2f2..eec6c1149f44 100644
--- a/tools/perf/util/svghelper.c
+++ b/tools/perf/util/svghelper.c
@@ -748,7 +748,7 @@ static int str_to_bitmap(char *s, cpumask_t *b)
 		set_bit(c, cpumask_bits(b));
 	}
 
-	cpu_map__delete(m);
+	cpu_map__put(m);
 
 	return ret;
 }
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 04/25] perf tools: Add reference counting for thread_map object
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (2 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 03/25] perf tools: Add reference counting for cpu_map object Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 19:08   ` Arnaldo Carvalho de Melo
  2015-06-10 18:10 ` [PATCH 05/25] perf tools: Propagate cpu maps through the evlist Jiri Olsa
                   ` (21 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Adding refference counting for thread_map object, so
it could be easily shared among other objects.

Using thread_map__put instead thread_map__delete and making
thread_map__delete static.

Link: http://lkml.kernel.org/n/tip-myadl53clbkjvzeqolwp95w0@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/tests/code-reading.c            |  2 +-
 tools/perf/tests/keep-tracking.c           |  2 +-
 tools/perf/tests/mmap-basic.c              |  2 +-
 tools/perf/tests/mmap-thread-lookup.c      |  2 +-
 tools/perf/tests/openat-syscall-all-cpus.c |  2 +-
 tools/perf/tests/openat-syscall.c          |  2 +-
 tools/perf/tests/switch-tracking.c         |  2 +-
 tools/perf/util/evlist.c                   |  4 ++--
 tools/perf/util/python.c                   |  2 +-
 tools/perf/util/thread_map.c               | 28 ++++++++++++++++++++++++++--
 tools/perf/util/thread_map.h               |  6 ++++--
 11 files changed, 40 insertions(+), 14 deletions(-)

diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 86d17d2e9e50..7dcd2c3d865f 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -546,7 +546,7 @@ out_err:
 		perf_evlist__delete(evlist);
 	} else {
 		cpu_map__put(cpus);
-		thread_map__delete(threads);
+		thread_map__put(threads);
 	}
 	machines__destroy_kernel_maps(&machines);
 	machine__delete_threads(machine);
diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
index a330235cefc0..4d4b9837b630 100644
--- a/tools/perf/tests/keep-tracking.c
+++ b/tools/perf/tests/keep-tracking.c
@@ -145,7 +145,7 @@ out_err:
 		perf_evlist__delete(evlist);
 	} else {
 		cpu_map__put(cpus);
-		thread_map__delete(threads);
+		thread_map__put(threads);
 	}
 
 	return err;
diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
index 5a9ef5833452..666b67a4df9d 100644
--- a/tools/perf/tests/mmap-basic.c
+++ b/tools/perf/tests/mmap-basic.c
@@ -142,6 +142,6 @@ out_delete_evlist:
 out_free_cpus:
 	cpu_map__put(cpus);
 out_free_threads:
-	thread_map__delete(threads);
+	thread_map__put(threads);
 	return err;
 }
diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c
index 264e215c0d36..412a41eb3f81 100644
--- a/tools/perf/tests/mmap-thread-lookup.c
+++ b/tools/perf/tests/mmap-thread-lookup.c
@@ -143,7 +143,7 @@ static int synth_process(struct machine *machine)
 						perf_event__process,
 						machine, 0);
 
-	thread_map__delete(map);
+	thread_map__put(map);
 	return err;
 }
 
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index e34dfdf96b5a..8801983a38f0 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -110,6 +110,6 @@ out_close_fd:
 out_evsel_delete:
 	perf_evsel__delete(evsel);
 out_thread_map_delete:
-	thread_map__delete(threads);
+	thread_map__put(threads);
 	return err;
 }
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
index 9f9491bb8e48..bdfa1f446681 100644
--- a/tools/perf/tests/openat-syscall.c
+++ b/tools/perf/tests/openat-syscall.c
@@ -56,6 +56,6 @@ out_close_fd:
 out_evsel_delete:
 	perf_evsel__delete(evsel);
 out_thread_map_delete:
-	thread_map__delete(threads);
+	thread_map__put(threads);
 	return err;
 }
diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
index 1b06122beb76..e698742d4fec 100644
--- a/tools/perf/tests/switch-tracking.c
+++ b/tools/perf/tests/switch-tracking.c
@@ -561,7 +561,7 @@ out:
 		perf_evlist__delete(evlist);
 	} else {
 		cpu_map__put(cpus);
-		thread_map__delete(threads);
+		thread_map__put(threads);
 	}
 
 	return err;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 6b895de1144d..493675cfa90c 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -115,7 +115,7 @@ void perf_evlist__delete(struct perf_evlist *evlist)
 	perf_evlist__munmap(evlist);
 	perf_evlist__close(evlist);
 	cpu_map__put(evlist->cpus);
-	thread_map__delete(evlist->threads);
+	thread_map__put(evlist->threads);
 	evlist->cpus = NULL;
 	evlist->threads = NULL;
 	perf_evlist__purge(evlist);
@@ -1104,7 +1104,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
 	return 0;
 
 out_delete_threads:
-	thread_map__delete(evlist->threads);
+	thread_map__put(evlist->threads);
 	evlist->threads = NULL;
 	return -1;
 }
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index b106d56df240..626422eda727 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -453,7 +453,7 @@ static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
 
 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
 {
-	thread_map__delete(pthreads->threads);
+	thread_map__put(pthreads->threads);
 	pthreads->ob_type->tp_free((PyObject*)pthreads);
 }
 
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index f93b9734735b..04bc15e339dd 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -8,6 +8,7 @@
 #include <unistd.h>
 #include "strlist.h"
 #include <string.h>
+#include "asm/bug.h"
 #include "thread_map.h"
 #include "util.h"
 
@@ -38,6 +39,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid)
 		for (i = 0; i < items; i++)
 			threads->map[i] = atoi(namelist[i]->d_name);
 		threads->nr = items;
+		threads->refcnt = 1;
 	}
 
 	for (i=0; i<items; i++)
@@ -54,6 +56,7 @@ struct thread_map *thread_map__new_by_tid(pid_t tid)
 	if (threads != NULL) {
 		threads->map[0] = tid;
 		threads->nr	= 1;
+		threads->refcnt = 1;
 	}
 
 	return threads;
@@ -75,6 +78,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
 		goto out_free_threads;
 
 	threads->nr = 0;
+	threads->refcnt = 1;
 
 	while (!readdir_r(proc, &dirent, &next) && next) {
 		char *end;
@@ -202,6 +206,8 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
 
 out:
 	strlist__delete(slist);
+	if (threads)
+		threads->refcnt = 1;
 	return threads;
 
 out_free_namelist:
@@ -221,6 +227,7 @@ struct thread_map *thread_map__new_dummy(void)
 	if (threads != NULL) {
 		threads->map[0]	= -1;
 		threads->nr	= 1;
+		threads->refcnt = 1;
 	}
 	return threads;
 }
@@ -263,6 +270,8 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
 		threads->nr		 = ntasks;
 	}
 out:
+	if (threads)
+		threads->refcnt = 1;
 	return threads;
 
 out_free_threads:
@@ -282,9 +291,24 @@ struct thread_map *thread_map__new_str(const char *pid, const char *tid,
 	return thread_map__new_by_tid_str(tid);
 }
 
-void thread_map__delete(struct thread_map *threads)
+static void thread_map__delete(struct thread_map *threads)
 {
-	free(threads);
+	if (threads) {
+		WARN_ONCE(threads->refcnt != 0, "thread map refcnt disbalanced\n");
+		free(threads);
+	}
+}
+
+struct thread_map *thread_map__get(struct thread_map *map)
+{
+	map->refcnt++;
+	return map;
+}
+
+void thread_map__put(struct thread_map *map)
+{
+	if (map && --map->refcnt == 0)
+		thread_map__delete(map);
 }
 
 size_t thread_map__fprintf(struct thread_map *threads, FILE *fp)
diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h
index 95313f43cc0f..dc02c259da36 100644
--- a/tools/perf/util/thread_map.h
+++ b/tools/perf/util/thread_map.h
@@ -5,6 +5,7 @@
 #include <stdio.h>
 
 struct thread_map {
+	int refcnt;
 	int nr;
 	pid_t map[];
 };
@@ -15,11 +16,12 @@ struct thread_map *thread_map__new_by_tid(pid_t tid);
 struct thread_map *thread_map__new_by_uid(uid_t uid);
 struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid);
 
+struct thread_map *thread_map__get(struct thread_map *map);
+void thread_map__put(struct thread_map *map);
+
 struct thread_map *thread_map__new_str(const char *pid,
 		const char *tid, uid_t uid);
 
-void thread_map__delete(struct thread_map *threads);
-
 size_t thread_map__fprintf(struct thread_map *threads, FILE *fp);
 
 static inline int thread_map__nr(struct thread_map *threads)
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 05/25] perf tools: Propagate cpu maps through the evlist
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (3 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 04/25] perf tools: Add reference counting for thread_map object Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 19:10   ` Arnaldo Carvalho de Melo
  2015-06-10 18:10 ` [PATCH 06/25] perf tools: Propagate thread " Jiri Olsa
                   ` (20 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Propagate evlist's cpu_map object through all the evsel objects,
while keeping already configured evsel->cpus.

It'll be handy to access evsel's cpus directly
in following patches.

Link: http://lkml.kernel.org/n/tip-myadl53clbkjvzeqolwp95w0@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/evlist.c | 24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 493675cfa90c..7cb579ca5629 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1085,6 +1085,28 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
 	return perf_evlist__mmap_ex(evlist, pages, overwrite, 0, false);
 }
 
+static int propagate_maps(struct perf_evlist *evlist, struct target *target)
+{
+	struct perf_evsel *evsel;
+
+	evlist__for_each(evlist, evsel) {
+		/*
+		 * We already have cpus for evsel (via PMU sysfs) so
+		 * keep it, if there's no target cpu list defined.
+		 */
+		if (evsel->cpus && target->cpu_list)
+			cpu_map__put(evsel->cpus);
+
+		if (!evsel->cpus || target->cpu_list)
+			evsel->cpus = cpu_map__get(evlist->cpus);
+
+		if (!evsel->cpus)
+			return -ENOMEM;
+	}
+
+	return 0;
+}
+
 int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
 {
 	evlist->threads = thread_map__new_str(target->pid, target->tid,
@@ -1101,7 +1123,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
 	if (evlist->cpus == NULL)
 		goto out_delete_threads;
 
-	return 0;
+	return propagate_maps(evlist, target);
 
 out_delete_threads:
 	thread_map__put(evlist->threads);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 06/25] perf tools: Propagate thread maps through the evlist
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (4 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 05/25] perf tools: Propagate cpu maps through the evlist Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 19:09   ` Arnaldo Carvalho de Melo
  2015-06-10 18:10 ` [PATCH 07/25] perf tools: Make perf_evsel__(nr_)cpus generic Jiri Olsa
                   ` (19 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Propagate evlist's thread_map object through all the
evsel objects.

It'll be handy to access evsel's threads directly
in following patches.

Link: http://lkml.kernel.org/n/tip-6vc92bytyy2d6c5entm5s698@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/evlist.c | 4 +++-
 tools/perf/util/evsel.c  | 1 +
 tools/perf/util/evsel.h  | 1 +
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 7cb579ca5629..f438881040f2 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1100,7 +1100,9 @@ static int propagate_maps(struct perf_evlist *evlist, struct target *target)
 		if (!evsel->cpus || target->cpu_list)
 			evsel->cpus = cpu_map__get(evlist->cpus);
 
-		if (!evsel->cpus)
+		evsel->threads = thread_map__get(evlist->threads);
+
+		if (!evsel->cpus || !evsel->threads)
 			return -ENOMEM;
 	}
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 3bd5769dd7b9..bd1c3b71e455 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -903,6 +903,7 @@ void perf_evsel__exit(struct perf_evsel *evsel)
 	perf_evsel__free_id(evsel);
 	close_cgroup(evsel->cgrp);
 	cpu_map__put(evsel->cpus);
+	thread_map__put(evsel->threads);
 	zfree(&evsel->group_name);
 	zfree(&evsel->name);
 	perf_evsel__object.fini(evsel);
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 21ec08247d47..d18572223b08 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -82,6 +82,7 @@ struct perf_evsel {
 	struct cgroup_sel	*cgrp;
 	void			*handler;
 	struct cpu_map		*cpus;
+	struct thread_map	*threads;
 	unsigned int		sample_size;
 	int			id_pos;
 	int			is_pos;
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 07/25] perf tools: Make perf_evsel__(nr_)cpus generic
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (5 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 06/25] perf tools: Propagate thread " Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 08/25] perf stat: Introduce perf_counts__(alloc|free|reset) functions Jiri Olsa
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Because we now propagate all evlist's cpu_maps and thread_map
objects through all evsels, the perf_evsel__(nr_)cpus no longer
need to be specific to stat object and check evlist and target
objects.

Link: http://lkml.kernel.org/n/tip-3pp2i969cmewv580k6qvd3up@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 10 ----------
 tools/perf/util/evsel.h   | 11 +++++++++++
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index ff3d25803400..79a596fcfd6c 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -141,16 +141,6 @@ static inline void diff_timespec(struct timespec *r, struct timespec *a,
 	}
 }
 
-static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel)
-{
-	return (evsel->cpus && !target.cpu_list) ? evsel->cpus : evsel_list->cpus;
-}
-
-static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
-{
-	return perf_evsel__cpus(evsel)->nr;
-}
-
 static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
 {
 	int i;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index d18572223b08..54afdc80a651 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -8,6 +8,7 @@
 #include <linux/types.h>
 #include "xyarray.h"
 #include "symbol.h"
+#include "cpumap.h"
 
 struct perf_counts_values {
 	union {
@@ -114,6 +115,16 @@ struct thread_map;
 struct perf_evlist;
 struct record_opts;
 
+static inline struct cpu_map *perf_evsel__cpus(struct perf_evsel *evsel)
+{
+	return evsel->cpus;
+}
+
+static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
+{
+	return perf_evsel__cpus(evsel)->nr;
+}
+
 void perf_counts_values__scale(struct perf_counts_values *count,
 			       bool scale, s8 *pscaled);
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 08/25] perf stat: Introduce perf_counts__(alloc|free|reset) functions
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (6 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 07/25] perf tools: Make perf_evsel__(nr_)cpus generic Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:54   ` Arnaldo Carvalho de Melo
  2015-06-10 18:10 ` [PATCH 09/25] perf stat: Introduce perf_counts function Jiri Olsa
                   ` (17 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Move 'struct perf_counts' allocation|free|reset code into
separate functions.

Link: http://lkml.kernel.org/n/tip-qu64zmm5zbpbkuybusnkg4gl@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 19 +++++++------------
 tools/perf/util/evsel.c   | 28 +++++++++++++++++++++++-----
 tools/perf/util/evsel.h   |  3 +++
 3 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 79a596fcfd6c..90766538fd8f 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -168,24 +168,19 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
 
 static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
 {
-	void *addr;
-	size_t sz;
+	struct perf_counts *counts;
 
-	sz = sizeof(*evsel->counts) +
-	     (perf_evsel__nr_cpus(evsel) * sizeof(struct perf_counts_values));
+	counts = perf_counts__alloc(perf_evsel__nr_cpus(evsel));
+	if (counts)
+		evsel->prev_raw_counts = counts;
 
-	addr = zalloc(sz);
-	if (!addr)
-		return -ENOMEM;
-
-	evsel->prev_raw_counts =  addr;
-
-	return 0;
+	return counts ? 0 : -ENOMEM;
 }
 
 static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
 {
-	zfree(&evsel->prev_raw_counts);
+	perf_counts__free(evsel->prev_raw_counts);
+	evsel->prev_raw_counts = NULL;
 }
 
 static void perf_evlist__free_stats(struct perf_evlist *evlist)
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index bd1c3b71e455..fde2416921cc 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -851,16 +851,33 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
 	return 0;
 }
 
+struct perf_counts *perf_counts__alloc(int ncpus)
+{
+	int size = sizeof(struct perf_counts) +
+		   ncpus * sizeof(struct perf_counts_values);
+
+	return zalloc(size);
+}
+
+void perf_counts__free(struct perf_counts *counts)
+{
+	free(counts);
+}
+
+static void perf_counts__reset(struct perf_counts *counts, int ncpus)
+{
+	memset(counts, 0, (sizeof(*counts) +
+	       (ncpus * sizeof(struct perf_counts_values))));
+}
+
 void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
 {
-	memset(evsel->counts, 0, (sizeof(*evsel->counts) +
-				 (ncpus * sizeof(struct perf_counts_values))));
+	perf_counts__reset(evsel->counts, ncpus);
 }
 
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
 {
-	evsel->counts = zalloc((sizeof(*evsel->counts) +
-				(ncpus * sizeof(struct perf_counts_values))));
+	evsel->counts = perf_counts__alloc(ncpus);
 	return evsel->counts != NULL ? 0 : -ENOMEM;
 }
 
@@ -893,7 +910,8 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
 
 void perf_evsel__free_counts(struct perf_evsel *evsel)
 {
-	zfree(&evsel->counts);
+	perf_counts__free(evsel->counts);
+	evsel->counts = NULL;
 }
 
 void perf_evsel__exit(struct perf_evsel *evsel)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 54afdc80a651..ef619645a08f 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -131,6 +131,9 @@ void perf_counts_values__scale(struct perf_counts_values *count,
 void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
 				struct perf_counts_values *count);
 
+struct perf_counts *perf_counts__alloc(int ncpus);
+void perf_counts__free(struct perf_counts *counts);
+
 int perf_evsel__object_config(size_t object_size,
 			      int (*init)(struct perf_evsel *evsel),
 			      void (*fini)(struct perf_evsel *evsel));
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 09/25] perf stat: Introduce perf_counts function
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (7 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 08/25] perf stat: Introduce perf_counts__(alloc|free|reset) functions Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 10/25] perf stat: Use xyarray for cpu evsel counts Jiri Olsa
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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

Link: http://lkml.kernel.org/n/tip-qu64zmm5zbpbkuybusnkg4gl@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 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                    |  6 ++++++
 5 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 90766538fd8f..7d1aebd5e1e4 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -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;
@@ -802,9 +802,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)
@@ -912,9 +912,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);
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index 8801983a38f0..a89a39f282ea 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -97,9 +97,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;
 		}
 	}
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
index bdfa1f446681..e86fc477a74f 100644
--- a/tools/perf/tests/openat-syscall.c
+++ b/tools/perf/tests/openat-syscall.c
@@ -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;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index fde2416921cc..1a6bdd16ec37 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -945,8 +945,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;
@@ -1007,7 +1007,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;
 }
 
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index ef619645a08f..3037c24e1fea 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -134,6 +134,12 @@ void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
 struct perf_counts *perf_counts__alloc(int ncpus);
 void perf_counts__free(struct perf_counts *counts);
 
+static inline struct perf_counts_values*
+perf_counts(struct perf_counts *counts, int cpu)
+{
+	return &counts->cpu[cpu];
+}
+
 int perf_evsel__object_config(size_t object_size,
 			      int (*init)(struct perf_evsel *evsel),
 			      void (*fini)(struct perf_evsel *evsel));
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 10/25] perf stat: Use xyarray for cpu evsel counts
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (8 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 09/25] perf stat: Introduce perf_counts function Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 11/25] perf stat: Make stats work over the thread dimension Jiri Olsa
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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

Link: http://lkml.kernel.org/n/tip-t1wefzwb3z78sjlpzt95lw61@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c         |  2 +-
 tools/perf/tests/openat-syscall.c |  2 +-
 tools/perf/util/evsel.c           | 31 ++++++++++++++++++++++---------
 tools/perf/util/evsel.h           |  6 +++---
 4 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 7d1aebd5e1e4..2221a75e11e5 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -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();
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
index e86fc477a74f..bd882f09ebbc 100644
--- a/tools/perf/tests/openat-syscall.c
+++ b/tools/perf/tests/openat-syscall.c
@@ -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;
 	}
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 1a6bdd16ec37..e69a7ee4cc0b 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -853,26 +853,39 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
 
 struct perf_counts *perf_counts__alloc(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__free(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__zero(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)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 3037c24e1fea..12e87f917d44 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -24,7 +24,7 @@ struct perf_counts_values {
 struct perf_counts {
 	s8		   	  scaled;
 	struct perf_counts_values aggr;
-	struct perf_counts_values cpu[];
+	struct xyarray		  *cpu;
 };
 
 struct perf_evsel;
@@ -137,7 +137,7 @@ void perf_counts__free(struct perf_counts *counts);
 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);
 }
 
 int perf_evsel__object_config(size_t object_size,
@@ -192,7 +192,7 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
 
 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus);
-void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus);
+void perf_evsel__reset_counts(struct perf_evsel *evsel);
 void perf_evsel__free_counts(struct perf_evsel *evsel);
 void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 11/25] perf stat: Make stats work over the thread dimension
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (9 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 10/25] perf stat: Use xyarray for cpu evsel counts Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 12/25] perf stat: Rename struct perf_counts::cpu member to values Jiri Olsa
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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

Link: http://lkml.kernel.org/n/tip-vvu96knzwli7ajpjz7qu8jfl@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 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                    | 20 +++++++++----------
 tools/perf/util/evsel.h                    | 10 +++++-----
 5 files changed, 38 insertions(+), 34 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 2221a75e11e5..8359f6dad441 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -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__alloc(perf_evsel__nr_cpus(evsel));
+	counts = perf_counts__alloc(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++)
@@ -802,9 +806,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)
@@ -912,9 +916,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);
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
index a89a39f282ea..d943c8b18fe1 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -77,7 +77,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;
 	}
@@ -97,9 +97,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;
 		}
 	}
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
index bd882f09ebbc..c9a37bc6b33a 100644
--- a/tools/perf/tests/openat-syscall.c
+++ b/tools/perf/tests/openat-syscall.c
@@ -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;
 	}
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index e69a7ee4cc0b..b9f798732866 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -851,14 +851,14 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
 	return 0;
 }
 
-struct perf_counts *perf_counts__alloc(int ncpus)
+struct perf_counts *perf_counts__alloc(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;
@@ -888,9 +888,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__alloc(ncpus);
+	evsel->counts = perf_counts__alloc(ncpus, nthreads);
 	return evsel->counts != NULL ? 0 : -ENOMEM;
 }
 
@@ -946,7 +946,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;
@@ -958,8 +958,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;
@@ -1012,15 +1012,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;
 }
 
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 12e87f917d44..5e3a9d875137 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -128,16 +128,16 @@ 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);
 
-struct perf_counts *perf_counts__alloc(int ncpus);
+struct perf_counts *perf_counts__alloc(int ncpus, int nthreads);
 void perf_counts__free(struct perf_counts *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);
 }
 
 int perf_evsel__object_config(size_t object_size,
@@ -191,7 +191,7 @@ const char *perf_evsel__group_name(struct perf_evsel *evsel);
 int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
 
 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
-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__reset_counts(struct perf_evsel *evsel);
 void perf_evsel__free_counts(struct perf_evsel *evsel);
 void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 12/25] perf stat: Rename struct perf_counts::cpu member to values
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (10 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 11/25] perf stat: Make stats work over the thread dimension Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 13/25] perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into evsel object Jiri Olsa
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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

Link: http://lkml.kernel.org/n/tip-fee055ta61vlnjfjzurmy6qi@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/evsel.c | 12 ++++++------
 tools/perf/util/evsel.h |  4 ++--
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index b9f798732866..a5409d39392e 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -856,15 +856,15 @@ struct perf_counts *perf_counts__alloc(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;
@@ -873,14 +873,14 @@ struct perf_counts *perf_counts__alloc(int ncpus, int nthreads)
 void perf_counts__free(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__zero(counts->cpu);
+	xyarray__zero(counts->values);
 }
 
 void perf_evsel__reset_counts(struct perf_evsel *evsel)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 5e3a9d875137..0d495bd161c3 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -24,7 +24,7 @@ struct perf_counts_values {
 struct perf_counts {
 	s8		   	  scaled;
 	struct perf_counts_values aggr;
-	struct xyarray		  *cpu;
+	struct xyarray		  *values;
 };
 
 struct perf_evsel;
@@ -137,7 +137,7 @@ void perf_counts__free(struct perf_counts *counts);
 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);
 }
 
 int perf_evsel__object_config(size_t object_size,
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 13/25] perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into evsel object
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (11 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 12/25] perf stat: Rename struct perf_counts::cpu member to values Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:49   ` Arnaldo Carvalho de Melo
  2015-06-10 18:10 ` [PATCH 14/25] perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts " Jiri Olsa
                   ` (12 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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

Link: http://lkml.kernel.org/n/tip-ti0tocuk8fuw0zb7puyuw4e7@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 25 -------------------------
 tools/perf/util/evsel.c   | 26 ++++++++++++++++++++++++++
 tools/perf/util/evsel.h   |  5 +++++
 3 files changed, 31 insertions(+), 25 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 8359f6dad441..d6f23c3436ae 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -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)
 {
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index a5409d39392e..7375dcc634da 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -26,6 +26,7 @@
 #include "perf_regs.h"
 #include "debug.h"
 #include "trace-event.h"
+#include "stat.h"
 
 static struct {
 	bool sample_id_all;
@@ -851,6 +852,31 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
 	return 0;
 }
 
+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);
+}
+
 struct perf_counts *perf_counts__alloc(int ncpus, int nthreads)
 {
 	struct perf_counts *counts = zalloc(sizeof(*counts));
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 0d495bd161c3..051175098f0b 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -192,6 +192,11 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
 
 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads);
+
+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);
+
 void perf_evsel__reset_counts(struct perf_evsel *evsel);
 void perf_evsel__free_counts(struct perf_evsel *evsel);
 void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 14/25] perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts into evsel object
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (12 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 13/25] perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into evsel object Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 15/25] perf stat: Move perf_evlist__(alloc|free)_stats into evlist object Jiri Olsa
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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

Link: http://lkml.kernel.org/n/tip-am4oi22oasuy97bc4mt8i33e@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 18 ------------------
 tools/perf/util/evsel.c   | 18 ++++++++++++++++++
 tools/perf/util/evsel.h   |  4 ++++
 3 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index d6f23c3436ae..b15fc47aa673 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -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__alloc(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__free(evsel->prev_raw_counts);
-	evsel->prev_raw_counts = NULL;
-}
-
 static void perf_evlist__free_stats(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 7375dcc634da..d5680f210fc4 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -852,6 +852,24 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
 	return 0;
 }
 
+int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
+				      int ncpus, int nthreads)
+{
+	struct perf_counts *counts;
+
+	counts = perf_counts__alloc(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__free(evsel->prev_raw_counts);
+	evsel->prev_raw_counts = NULL;
+}
+
 void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
 {
 	int i;
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 051175098f0b..d16ed197c00a 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -193,6 +193,10 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads);
 
+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);
+
 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);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 15/25] perf stat: Move perf_evlist__(alloc|free)_stats into evlist object
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (13 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 14/25] perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts " Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 19:13   ` Arnaldo Carvalho de Melo
  2015-06-10 18:10 ` [PATCH 16/25] perf stat: Introduce perf_evsel__alloc_stats function Jiri Olsa
                   ` (10 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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

Link: http://lkml.kernel.org/n/tip-8dwmf838kipxabe0vay8h0zn@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 32 --------------------------------
 tools/perf/util/evlist.c  | 32 ++++++++++++++++++++++++++++++++
 tools/perf/util/evlist.h  |  2 ++
 3 files changed, 34 insertions(+), 32 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index b15fc47aa673..5072ca809c23 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -141,38 +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_stat__reset_stats(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index f438881040f2..44d52a07223c 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1651,3 +1651,35 @@ void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
 
 	tracking_evsel->tracking = true;
 }
+
+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))
+			goto out_free;
+	}
+
+	return 0;
+
+out_free:
+	perf_evlist__free_stats(evlist);
+	return -1;
+}
+
+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);
+	}
+}
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 955bf31b7dd3..557083673bab 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -288,4 +288,6 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
 void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
 				     struct perf_evsel *tracking_evsel);
 
+int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw);
+void perf_evlist__free_stats(struct perf_evlist *evlist);
 #endif /* __PERF_EVLIST_H */
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 16/25] perf stat: Introduce perf_evsel__alloc_stats function
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (14 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 15/25] perf stat: Move perf_evlist__(alloc|free)_stats into evlist object Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 17/25] perf stat: Introduce perf_evsel__read function Jiri Olsa
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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

Link: http://lkml.kernel.org/n/tip-hclg66nszn5mx8t9uwrxxw6b@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/evlist.c |  7 +------
 tools/perf/util/evsel.c  | 13 +++++++++++++
 tools/perf/util/evsel.h  |  2 ++
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 44d52a07223c..73db625ed1ce 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1655,14 +1655,9 @@ void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
 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;
 	}
 
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index d5680f210fc4..1608e29ab83d 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -938,6 +938,19 @@ int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads)
 	return evsel->counts != NULL ? 0 : -ENOMEM;
 }
 
+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;
+}
+
 static void perf_evsel__free_fd(struct perf_evsel *evsel)
 {
 	xyarray__delete(evsel->fd);
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index d16ed197c00a..80929965f0f5 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -201,6 +201,8 @@ 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_stats(struct perf_evsel *evsel, bool alloc_raw);
+
 void perf_evsel__reset_counts(struct perf_evsel *evsel);
 void perf_evsel__free_counts(struct perf_evsel *evsel);
 void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 17/25] perf stat: Introduce perf_evsel__read function
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (15 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 16/25] perf stat: Introduce perf_evsel__alloc_stats function Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 18/25] perf stat: Introduce read_counters function Jiri Olsa
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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

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

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 1608e29ab83d..c1d210f8e799 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1060,6 +1060,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)
 {
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 80929965f0f5..9609df91abc1 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -275,6 +275,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);
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 18/25] perf stat: Introduce read_counters function
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (16 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 17/25] perf stat: Introduce perf_evsel__read function Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 19/25] perf stat: Separate counters reading and processing Jiri Olsa
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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.

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

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 5072ca809c23..8fc40a3f3098 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -329,27 +329,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);
@@ -528,18 +536,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);
 }
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 19/25] perf stat: Separate counters reading and processing
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (17 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 18/25] perf stat: Introduce read_counters function Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 20/25] perf stat: Move zero_per_pkg into counter process code Jiri Olsa
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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.

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

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 8fc40a3f3098..59e1815e4def 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -223,8 +223,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;
@@ -245,7 +246,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;
@@ -262,23 +262,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);
@@ -321,7 +339,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;
 		}
 	}
@@ -338,10 +359,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),
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 20/25] perf stat: Move zero_per_pkg into counter process code
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (18 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 19/25] perf stat: Separate counters reading and processing Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 21/25] perf stat: Move perf_stat initialization " Jiri Olsa
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Moving zero_per_pkg into counter process code.

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

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 59e1815e4def..efc4d420f12e 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -291,6 +291,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;
@@ -334,9 +337,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;
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 21/25] perf stat: Move perf_stat initialization counter process code
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (19 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 20/25] perf stat: Move zero_per_pkg into counter process code Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:47   ` David Ahern
  2015-06-10 18:10 ` [PATCH 22/25] perf stat: Remove perf_evsel__read_cb function Jiri Olsa
                   ` (4 subsequent siblings)
  25 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Moving perf_stat initialization counter process code.

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

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index efc4d420f12e..3ababdb83aad 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -290,6 +290,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);
@@ -353,12 +354,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);
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 22/25] perf stat: Remove perf_evsel__read_cb function
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (20 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 21/25] perf stat: Move perf_stat initialization " Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 23/25] perf stat: Rename print_interval to process_interval Jiri Olsa
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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

Link: http://lkml.kernel.org/n/tip-5yh5pg1mw9wefhup1vvtssh9@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/evsel.c | 16 ----------------
 tools/perf/util/evsel.h |  7 -------
 2 files changed, 23 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index c1d210f8e799..ea76f821a251 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1044,22 +1044,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)
 {
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 9609df91abc1..d1f894ea6520 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -268,13 +268,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);
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 23/25] perf stat: Rename print_interval to process_interval
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (21 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 22/25] perf stat: Remove perf_evsel__read_cb function Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 24/25] perf stat: Introduce print_counters function Jiri Olsa
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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.

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

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 3ababdb83aad..d73ae0f134d1 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -369,7 +369,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;
@@ -529,7 +529,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);
@@ -547,7 +547,7 @@ static int __run_perf_stat(int argc, const char **argv)
 		while (!done) {
 			nanosleep(&ts, NULL);
 			if (interval)
-				print_interval();
+				process_interval();
 		}
 	}
 
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 24/25] perf stat: Introduce print_counters function
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (22 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 23/25] perf stat: Rename print_interval to process_interval Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:10 ` [PATCH 25/25] perf stat: Introduce --per-task option Jiri Olsa
  2015-06-10 18:16 ` [RFC/PATCH 00/25] " Jiri Olsa
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Centralize counters print code into single
print_counters function.

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

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index d73ae0f134d1..4a7cad8debac 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -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 = {
@@ -371,53 +368,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)
@@ -904,9 +862,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);
@@ -932,36 +916,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;
@@ -1410,13 +1411,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(evsel_list);
 		}
 	}
 
 	if (!forever && status != -1 && !interval)
-		print_stat(argc, argv);
+		print_counters(NULL, argc, argv);
 
 	perf_evlist__free_stats(evsel_list);
 out:
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH 25/25] perf stat: Introduce --per-task option
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (23 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 24/25] perf stat: Introduce print_counters function Jiri Olsa
@ 2015-06-10 18:10 ` Jiri Olsa
  2015-06-10 18:44   ` David Ahern
  2015-06-10 18:16 ` [RFC/PATCH 00/25] " Jiri Olsa
  25 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

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-task -p 12451,16173
  ^C
   Performance counter stats for process id '12451,16173':

  TASK-12451                77,784      cycles
  TASK-16173                64,809      cycles
  TASK-12451                14,432      instructions
  TASK-16173                14,452      instructions

         3.854957122 seconds time elapsed

Also woks under interval mode:

  $ ./perf stat -e cycles,instructions --per-task -p 16431,16173 -I 1000
  #           time task                      counts unit events
       1.000085816 TASK-16173                     0      cycles
       1.000085816 TASK-16431         3,358,360,926      cycles
       1.000085816 TASK-16173                     0      instructions
       1.000085816 TASK-16431         9,062,422,086      instructions
       2.000212262 TASK-16173                65,386      cycles
       2.000212262 TASK-16431         3,349,355,309      cycles
       2.000212262 TASK-16173                12,151      instructions
       2.000212262 TASK-16431         9,039,401,422      instructions
       3.000333402 TASK-16173                62,797      cycles
       3.000333402 TASK-16431         3,357,140,183      cycles
       3.000333402 TASK-16173                12,208      instructions
       3.000333402 TASK-16431         9,058,080,762      instructions
  ^C     3.375949851 TASK-16173                     0      cycles
       3.375949851 TASK-16431         1,264,764,804      cycles
       3.375949851 TASK-16173                     0      instructions
       3.375949851 TASK-16431         3,414,532,317      instructions

Link: http://lkml.kernel.org/n/tip-0v0ixd9k7o9z1u8hqngm1coe@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 57 +++++++++++++++++++++++++++++++++++++++++++++--
 tools/perf/util/stat.h    |  1 +
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 4a7cad8debac..293d1029e2ba 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -237,6 +237,7 @@ process_counter_values(struct perf_evsel *evsel, int cpu, int thread,
 		count = &zero;
 
 	switch (aggr_mode) {
+	case AGGR_TASK:
 	case AGGR_CORE:
 	case AGGR_SOCKET:
 	case AGGR_NONE:
@@ -605,6 +606,11 @@ static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
 			csv_output ? 0 : -4,
 			perf_evsel__cpus(evsel)->map[id], csv_sep);
 		break;
+	case AGGR_TASK:
+		fprintf(output, "TASK-%*d%s",
+			csv_output ? 0 : -8,
+			evsel->threads->map[id], csv_sep);
+		break;
 	case AGGR_GLOBAL:
 	default:
 		break;
@@ -753,6 +759,40 @@ static void print_aggr(char *prefix)
 	}
 }
 
+static void print_aggr_task(struct perf_evsel *counter, char *prefix)
+{
+	int nthreads = thread_map__nr(counter->threads);
+	int ncpus = cpu_map__nr(counter->cpus);
+	int cpu, thread;
+	double uval;
+
+	for (thread = 0; thread < nthreads; thread++) {
+		u64 ena = 0, run = 0, val = 0;
+
+		for (cpu = 0; cpu < ncpus; cpu++) {
+			val += perf_counts(counter->counts, cpu, thread)->val;
+			ena += perf_counts(counter->counts, cpu, thread)->ena;
+			run += perf_counts(counter->counts, cpu, thread)->run;
+		}
+
+		if (prefix)
+			fprintf(output, "%s", prefix);
+
+		uval = val * counter->scale;
+
+		if (nsec_counter(counter))
+			nsec_printout(thread, 0, counter, uval);
+		else
+			abs_printout(thread, 0, counter, uval);
+
+		if (!csv_output)
+			print_noise(counter, 1.0);
+
+		print_running(run, ena);
+		fputc('\n', output);
+	}
+}
+
 /*
  * Print out the results of a single counter:
  * aggregated counts in system-wide mode
@@ -879,6 +919,9 @@ static void print_interval(char *prefix, struct timespec *ts)
 		case AGGR_NONE:
 			fprintf(output, "#           time CPU                counts %*s events\n", unit_width, "unit");
 			break;
+		case AGGR_TASK:
+			fprintf(output, "#           time task                      counts %*s events\n", unit_width, "unit");
+			break;
 		case AGGR_GLOBAL:
 		default:
 			fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
@@ -947,6 +990,10 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
 	case AGGR_SOCKET:
 		print_aggr(prefix);
 		break;
+	case AGGR_TASK:
+		evlist__for_each(evsel_list, counter)
+			print_aggr_task(counter, prefix);
+		break;
 	case AGGR_GLOBAL:
 		evlist__for_each(evsel_list, counter)
 			print_counter_aggr(counter, prefix);
@@ -1034,6 +1081,7 @@ static int perf_stat_init_aggr_mode(void)
 		break;
 	case AGGR_NONE:
 	case AGGR_GLOBAL:
+	case AGGR_TASK:
 	default:
 		break;
 	}
@@ -1258,6 +1306,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 		     "aggregate counts per processor socket", AGGR_SOCKET),
 	OPT_SET_UINT(0, "per-core", &aggr_mode,
 		     "aggregate counts per physical processor core", AGGR_CORE),
+	OPT_SET_UINT(0, "per-task", &aggr_mode,
+		     "aggregate counts per task", AGGR_TASK),
 	OPT_UINTEGER('D', "delay", &initial_delay,
 		     "ms to wait before starting measurement after program start"),
 	OPT_END()
@@ -1349,8 +1399,11 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 		run_count = 1;
 	}
 
-	/* no_aggr, cgroup are for system-wide only */
-	if ((aggr_mode != AGGR_GLOBAL || nr_cgroups) &&
+	/*
+	 * no_aggr, cgroup are for system-wide only
+	 * --per-task is aggregated per task, we dont mix it with cpu mode
+	 */
+	if (((aggr_mode != AGGR_GLOBAL && aggr_mode != AGGR_TASK) || nr_cgroups) &&
 	    !target__has_cpu(&target)) {
 		fprintf(stderr, "both cgroup and no-aggregation "
 			"modes only available in system-wide mode\n");
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 615c779eb42a..e4c616af057d 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -29,6 +29,7 @@ enum aggr_mode {
 	AGGR_GLOBAL,
 	AGGR_SOCKET,
 	AGGR_CORE,
+	AGGR_TASK,
 };
 
 void update_stats(struct stats *stats, u64 val);
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [RFC/PATCH 00/25] perf stat: Introduce --per-task option
  2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
                   ` (24 preceding siblings ...)
  2015-06-10 18:10 ` [PATCH 25/25] perf stat: Introduce --per-task option Jiri Olsa
@ 2015-06-10 18:16 ` Jiri Olsa
  25 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:16 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, lkml, Adrian Hunter, Andi Kleen,
	David Ahern, Ingo Molnar, Namhyung Kim, Peter Zijlstra,
	Stephane Eranian

On Wed, Jun 10, 2015 at 08:10:33PM +0200, Jiri Olsa wrote:
> hi,
> adding the possibility to display stat data per thread.
> Allowing following commands and output:

available in here:
  git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
  perf/per_task

jirka

> 
>   $ perf stat -e cycles,instructions --per-task -p 12451,16173
>   ^C
>    Performance counter stats for process id '12451,16173':
> 
>   TASK-12451                77,784      cycles
>   TASK-16173                64,809      cycles
>   TASK-12451                14,432      instructions
>   TASK-16173                14,452      instructions
> 
>          3.854957122 seconds time elapsed
> 
> Also woks under interval mode:
> 
>   $ ./perf stat -e cycles,instructions --per-task -p 16431,16173 -I 1000
>   #           time task                      counts unit events
>        1.000085816 TASK-16173                     0      cycles
>        1.000085816 TASK-16431         3,358,360,926      cycles
>        1.000085816 TASK-16173                     0      instructions
>        1.000085816 TASK-16431         9,062,422,086      instructions
>        2.000212262 TASK-16173                65,386      cycles
>        2.000212262 TASK-16431         3,349,355,309      cycles
>        2.000212262 TASK-16173                12,151      instructions
>        2.000212262 TASK-16431         9,039,401,422      instructions
>        3.000333402 TASK-16173                62,797      cycles
>        3.000333402 TASK-16431         3,357,140,183      cycles
>        3.000333402 TASK-16173                12,208      instructions
>        3.000333402 TASK-16431         9,058,080,762      instructions
>   ^C     3.375949851 TASK-16173                     0      cycles
>        3.375949851 TASK-16431         1,264,764,804      cycles
>        3.375949851 TASK-16173                     0      instructions
>        3.375949851 TASK-16431         3,414,532,317      instructions
> 
> thanks for comments,
> jirka
> 
> 
> ---
> Jiri Olsa (25):
>       perf tools: Fix python code with missing stat dependency
>       perf tools: Introduce xyarray__zero function
>       perf tools: Add reference counting for cpu_map object
>       perf tools: Add reference counting for thread_map object
>       perf tools: Propagate cpu maps through the evlist
>       perf tools: Propagate thread maps through the evlist
>       perf tools: Make perf_evsel__(nr_)cpus generic
>       perf stat: Introduce perf_counts__(alloc|free|reset) functions
>       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: Move perf_evsel__(alloc|free|reset)_stat_priv into evsel object
>       perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts into evsel object
>       perf stat: Move perf_evlist__(alloc|free)_stats into evlist 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: Introduce print_counters function
>       perf stat: Introduce --per-task option
> 
>  tools/perf/builtin-stat.c                  | 388 +++++++++++++++++++++++++++++--------------------------------
>  tools/perf/tests/code-reading.c            |   4 +-
>  tools/perf/tests/keep-tracking.c           |   4 +-
>  tools/perf/tests/mmap-basic.c              |   4 +-
>  tools/perf/tests/mmap-thread-lookup.c      |   2 +-
>  tools/perf/tests/openat-syscall-all-cpus.c |   8 +-
>  tools/perf/tests/openat-syscall.c          |   6 +-
>  tools/perf/tests/switch-tracking.c         |   4 +-
>  tools/perf/util/cpumap.c                   |  24 +++-
>  tools/perf/util/cpumap.h                   |   5 +-
>  tools/perf/util/evlist.c                   |  61 +++++++++-
>  tools/perf/util/evlist.h                   |   2 +
>  tools/perf/util/evsel.c                    | 128 ++++++++++++++++----
>  tools/perf/util/evsel.h                    |  48 ++++++--
>  tools/perf/util/parse-events.c             |   5 +-
>  tools/perf/util/python-ext-sources         |   1 +
>  tools/perf/util/python.c                   |   4 +-
>  tools/perf/util/record.c                   |   4 +-
>  tools/perf/util/session.c                  |   2 +-
>  tools/perf/util/stat.h                     |   1 +
>  tools/perf/util/svghelper.c                |   2 +-
>  tools/perf/util/thread_map.c               |  28 ++++-
>  tools/perf/util/thread_map.h               |   6 +-
>  tools/perf/util/xyarray.c                  |   8 ++
>  tools/perf/util/xyarray.h                  |   2 +
>  25 files changed, 484 insertions(+), 267 deletions(-)

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 25/25] perf stat: Introduce --per-task option
  2015-06-10 18:10 ` [PATCH 25/25] perf stat: Introduce --per-task option Jiri Olsa
@ 2015-06-10 18:44   ` David Ahern
  2015-06-10 18:54     ` Jiri Olsa
  2015-06-10 19:28     ` Arnaldo Carvalho de Melo
  0 siblings, 2 replies; 54+ messages in thread
From: David Ahern @ 2015-06-10 18:44 UTC (permalink / raw)
  To: Jiri Olsa, Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, Ingo Molnar, Namhyung Kim,
	Peter Zijlstra, Stephane Eranian

On 6/10/15 12:10 PM, Jiri Olsa wrote:
> 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-task -p 12451,16173
>    ^C
>     Performance counter stats for process id '12451,16173':
>
>    TASK-12451                77,784      cycles
>    TASK-16173                64,809      cycles
>    TASK-12451                14,432      instructions
>    TASK-16173                14,452      instructions
>
>           3.854957122 seconds time elapsed
>
> Also woks under interval mode:
>
>    $ ./perf stat -e cycles,instructions --per-task -p 16431,16173 -I 1000
>    #           time task                      counts unit events
>         1.000085816 TASK-16173                     0      cycles
>         1.000085816 TASK-16431         3,358,360,926      cycles
>         1.000085816 TASK-16173                     0      instructions
>         1.000085816 TASK-16431         9,062,422,086      instructions
>         2.000212262 TASK-16173                65,386      cycles
>         2.000212262 TASK-16431         3,349,355,309      cycles
>         2.000212262 TASK-16173                12,151      instructions
>         2.000212262 TASK-16431         9,039,401,422      instructions
>         3.000333402 TASK-16173                62,797      cycles
>         3.000333402 TASK-16431         3,357,140,183      cycles
>         3.000333402 TASK-16173                12,208      instructions
>         3.000333402 TASK-16431         9,058,080,762      instructions
>    ^C     3.375949851 TASK-16173                     0      cycles
>         3.375949851 TASK-16431         1,264,764,804      cycles
>         3.375949851 TASK-16173                     0      instructions
>         3.375949851 TASK-16431         3,414,532,317      instructions
>

Why not print $comm-$pid versus TASK-$pid?


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 21/25] perf stat: Move perf_stat initialization counter process code
  2015-06-10 18:10 ` [PATCH 21/25] perf stat: Move perf_stat initialization " Jiri Olsa
@ 2015-06-10 18:47   ` David Ahern
  2015-06-10 20:21     ` Jiri Olsa
  0 siblings, 1 reply; 54+ messages in thread
From: David Ahern @ 2015-06-10 18:47 UTC (permalink / raw)
  To: Jiri Olsa, Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, Ingo Molnar, Namhyung Kim,
	Peter Zijlstra, Stephane Eranian

On 6/10/15 12:10 PM, Jiri Olsa wrote:
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index efc4d420f12e..3ababdb83aad 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -290,6 +290,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()?


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 13/25] perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into evsel object
  2015-06-10 18:10 ` [PATCH 13/25] perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into evsel object Jiri Olsa
@ 2015-06-10 18:49   ` Arnaldo Carvalho de Melo
  2015-06-10 20:21     ` Jiri Olsa
  0 siblings, 1 reply; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 18:49 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 08:10:46PM +0200, Jiri Olsa escreveu:
> Moving perf_evsel__(alloc|free|reset)_stat_priv into evsel object,
> so it could be used outside stat object in following patches.
 
> +++ b/tools/perf/util/evsel.c
  
> +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);
> +}

Please move this to some 'stat' specific place, so that evsel.c has
nothing that is tool specific, like references to 'struct perf_stat'.

- Arnaldo

> +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);
> +}
> +
>  struct perf_counts *perf_counts__alloc(int ncpus, int nthreads)
>  {
>  	struct perf_counts *counts = zalloc(sizeof(*counts));
> diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
> index 0d495bd161c3..051175098f0b 100644
> --- a/tools/perf/util/evsel.h
> +++ b/tools/perf/util/evsel.h
> @@ -192,6 +192,11 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size);
>  
>  int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads);
>  int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads);
> +
> +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);
> +
>  void perf_evsel__reset_counts(struct perf_evsel *evsel);
>  void perf_evsel__free_counts(struct perf_evsel *evsel);
>  void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads);
> -- 
> 1.9.3

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 25/25] perf stat: Introduce --per-task option
  2015-06-10 18:44   ` David Ahern
@ 2015-06-10 18:54     ` Jiri Olsa
  2015-06-10 19:28     ` Arnaldo Carvalho de Melo
  1 sibling, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 18:54 UTC (permalink / raw)
  To: David Ahern
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, lkml, Adrian Hunter,
	Andi Kleen, Ingo Molnar, Namhyung Kim, Peter Zijlstra,
	Stephane Eranian

On Wed, Jun 10, 2015 at 12:44:34PM -0600, David Ahern wrote:

SNIP

> >        2.000212262 TASK-16431         9,039,401,422      instructions
> >        3.000333402 TASK-16173                62,797      cycles
> >        3.000333402 TASK-16431         3,357,140,183      cycles
> >        3.000333402 TASK-16173                12,208      instructions
> >        3.000333402 TASK-16431         9,058,080,762      instructions
> >   ^C     3.375949851 TASK-16173                     0      cycles
> >        3.375949851 TASK-16431         1,264,764,804      cycles
> >        3.375949851 TASK-16173                     0      instructions
> >        3.375949851 TASK-16431         3,414,532,317      instructions
> >
> 
> Why not print $comm-$pid versus TASK-$pid?
> 

yep, good idea

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 08/25] perf stat: Introduce perf_counts__(alloc|free|reset) functions
  2015-06-10 18:10 ` [PATCH 08/25] perf stat: Introduce perf_counts__(alloc|free|reset) functions Jiri Olsa
@ 2015-06-10 18:54   ` Arnaldo Carvalho de Melo
  2015-06-10 20:22     ` Jiri Olsa
  0 siblings, 1 reply; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 18:54 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 08:10:41PM +0200, Jiri Olsa escreveu:
> Move 'struct perf_counts' allocation|free|reset code into
> separate functions.
> 
> Link: http://lkml.kernel.org/n/tip-qu64zmm5zbpbkuybusnkg4gl@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/builtin-stat.c | 19 +++++++------------
>  tools/perf/util/evsel.c   | 28 +++++++++++++++++++++++-----
>  tools/perf/util/evsel.h   |  3 +++
>  3 files changed, 33 insertions(+), 17 deletions(-)

But please do not move it to 'evsel.[ch]', i.e. you're introducing a new
class, i.e. "perf_counts", you might as well put them in a separate
file, i.e. tools/perf/util/counts.[ch].

And please rename perf_counts__alloc() to perf_counds__new(), ditto for
__free() -> __delete(), 
 
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index 79a596fcfd6c..90766538fd8f 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -168,24 +168,19 @@ static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
>  
>  static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
>  {
> -	void *addr;
> -	size_t sz;
> +	struct perf_counts *counts;
>  
> -	sz = sizeof(*evsel->counts) +
> -	     (perf_evsel__nr_cpus(evsel) * sizeof(struct perf_counts_values));
> +	counts = perf_counts__alloc(perf_evsel__nr_cpus(evsel));
> +	if (counts)
> +		evsel->prev_raw_counts = counts;
>  
> -	addr = zalloc(sz);
> -	if (!addr)
> -		return -ENOMEM;
> -
> -	evsel->prev_raw_counts =  addr;
> -
> -	return 0;
> +	return counts ? 0 : -ENOMEM;
>  }
>  
>  static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
>  {
> -	zfree(&evsel->prev_raw_counts);
> +	perf_counts__free(evsel->prev_raw_counts);
> +	evsel->prev_raw_counts = NULL;
>  }
>  
>  static void perf_evlist__free_stats(struct perf_evlist *evlist)
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index bd1c3b71e455..fde2416921cc 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -851,16 +851,33 @@ int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
>  	return 0;
>  }
>  
> +struct perf_counts *perf_counts__alloc(int ncpus)
> +{
> +	int size = sizeof(struct perf_counts) +
> +		   ncpus * sizeof(struct perf_counts_values);
> +
> +	return zalloc(size);
> +}
> +
> +void perf_counts__free(struct perf_counts *counts)
> +{
> +	free(counts);
> +}
> +
> +static void perf_counts__reset(struct perf_counts *counts, int ncpus)
> +{
> +	memset(counts, 0, (sizeof(*counts) +
> +	       (ncpus * sizeof(struct perf_counts_values))));
> +}
> +
>  void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
>  {
> -	memset(evsel->counts, 0, (sizeof(*evsel->counts) +
> -				 (ncpus * sizeof(struct perf_counts_values))));
> +	perf_counts__reset(evsel->counts, ncpus);
>  }
>  
>  int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
>  {
> -	evsel->counts = zalloc((sizeof(*evsel->counts) +
> -				(ncpus * sizeof(struct perf_counts_values))));
> +	evsel->counts = perf_counts__alloc(ncpus);
>  	return evsel->counts != NULL ? 0 : -ENOMEM;
>  }
>  
> @@ -893,7 +910,8 @@ void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
>  
>  void perf_evsel__free_counts(struct perf_evsel *evsel)
>  {
> -	zfree(&evsel->counts);
> +	perf_counts__free(evsel->counts);
> +	evsel->counts = NULL;
>  }
>  
>  void perf_evsel__exit(struct perf_evsel *evsel)
> diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
> index 54afdc80a651..ef619645a08f 100644
> --- a/tools/perf/util/evsel.h
> +++ b/tools/perf/util/evsel.h
> @@ -131,6 +131,9 @@ void perf_counts_values__scale(struct perf_counts_values *count,
>  void perf_evsel__compute_deltas(struct perf_evsel *evsel, int cpu,
>  				struct perf_counts_values *count);
>  
> +struct perf_counts *perf_counts__alloc(int ncpus);
> +void perf_counts__free(struct perf_counts *counts);
> +
>  int perf_evsel__object_config(size_t object_size,
>  			      int (*init)(struct perf_evsel *evsel),
>  			      void (*fini)(struct perf_evsel *evsel));
> -- 
> 1.9.3

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 01/25] perf tools: Fix python code with missing stat dependency
  2015-06-10 18:10 ` [PATCH 01/25] perf tools: Fix python code with missing stat dependency Jiri Olsa
@ 2015-06-10 18:55   ` Arnaldo Carvalho de Melo
  2015-06-10 20:23     ` Jiri Olsa
  0 siblings, 1 reply; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 18:55 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 08:10:34PM +0200, Jiri Olsa escreveu:
> The evsel object now depends on stat object and breaks
> python code because of missing stat object dependency.
> Putting stat.c object into python object list.

Applied, but 'perf test python'  was Okaying me before and after this
change, strange :-\

- Arnaldo
 
> Link: http://lkml.kernel.org/n/tip-o2cnaarx0buid9rtmtk5oorp@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/util/python-ext-sources | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
> index 4d28624a1eca..04fb68fc6def 100644
> --- a/tools/perf/util/python-ext-sources
> +++ b/tools/perf/util/python-ext-sources
> @@ -18,4 +18,5 @@ util/cgroup.c
>  util/rblist.c
>  util/strlist.c
>  util/trace-event.c
> +util/stat.c
>  ../../lib/rbtree.c
> -- 
> 1.9.3

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 02/25] perf tools: Introduce xyarray__zero function
  2015-06-10 18:10 ` [PATCH 02/25] perf tools: Introduce xyarray__zero function Jiri Olsa
@ 2015-06-10 19:06   ` Arnaldo Carvalho de Melo
  2015-06-10 20:01     ` Jiri Olsa
  0 siblings, 1 reply; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 19:06 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 08:10:35PM +0200, Jiri Olsa escreveu:
> To zero all the xyarray contents. It will be used
> in following patches.

I guess I would prefer xyarray__memset(), similar semantics as
'memset()', but I did a quick look and this is used in the kernel in
things like bitmap_zero() and wrappers to it have that semantic...

Interesting that we don't have anymore a bzero() like function, but
then, looking at 'man bzero':

----------------------------
CONFORMING TO

       4.3BSD.   This  function  is  deprecated  (marked  as  LEGACY  in
POSIX.1-2001): use memset(3) in new programs.  POSIX.1-2008 removes the
specification of bzero().

-----------------------------

Guess we should use 'xyarray__memset()', ok?

- Arnaldo
 
> Link: http://lkml.kernel.org/n/tip-bp8bcl46cav05xn0uacg7ytn@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/util/xyarray.c | 8 ++++++++
>  tools/perf/util/xyarray.h | 2 ++
>  2 files changed, 10 insertions(+)
> 
> diff --git a/tools/perf/util/xyarray.c b/tools/perf/util/xyarray.c
> index 22afbf6c536a..d0ca9ed5e7f2 100644
> --- a/tools/perf/util/xyarray.c
> +++ b/tools/perf/util/xyarray.c
> @@ -9,11 +9,19 @@ struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size)
>  	if (xy != NULL) {
>  		xy->entry_size = entry_size;
>  		xy->row_size   = row_size;
> +		xy->entries    = xlen * ylen;
>  	}
>  
>  	return xy;
>  }
>  
> +void xyarray__zero(struct xyarray *xy)
> +{
> +	size_t n = xy->entries * xy->entry_size;
> +
> +	memset(xy->contents, 0, n);
> +}
> +
>  void xyarray__delete(struct xyarray *xy)
>  {
>  	free(xy);
> diff --git a/tools/perf/util/xyarray.h b/tools/perf/util/xyarray.h
> index c488a07275dd..60cd80acdaa9 100644
> --- a/tools/perf/util/xyarray.h
> +++ b/tools/perf/util/xyarray.h
> @@ -6,11 +6,13 @@
>  struct xyarray {
>  	size_t row_size;
>  	size_t entry_size;
> +	size_t entries;
>  	char contents[];
>  };
>  
>  struct xyarray *xyarray__new(int xlen, int ylen, size_t entry_size);
>  void xyarray__delete(struct xyarray *xy);
> +void xyarray__zero(struct xyarray *xy);
>  
>  static inline void *xyarray__entry(struct xyarray *xy, int x, int y)
>  {
> -- 
> 1.9.3

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 03/25] perf tools: Add reference counting for cpu_map object
  2015-06-10 18:10 ` [PATCH 03/25] perf tools: Add reference counting for cpu_map object Jiri Olsa
@ 2015-06-10 19:07   ` Arnaldo Carvalho de Melo
  2015-06-10 20:07     ` Jiri Olsa
  0 siblings, 1 reply; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 19:07 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 08:10:36PM +0200, Jiri Olsa escreveu:
> Adding refference counting for cpu_map object, so
> it could be easily shared among other objects.
> 
> Using cpu_map__put instead cpu_map__delete and making
> cpu_map__delete static.

Please use atomic.h, as was done recently for the 'map', 'dso' and
'thread' structs, but other than that, its fine.

- Arnaldo
 
> Link: http://lkml.kernel.org/n/tip-gwy96ohuwhjz603bnf70af6i@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/tests/code-reading.c    |  2 +-
>  tools/perf/tests/keep-tracking.c   |  2 +-
>  tools/perf/tests/mmap-basic.c      |  2 +-
>  tools/perf/tests/switch-tracking.c |  2 +-
>  tools/perf/util/cpumap.c           | 24 ++++++++++++++++++++++--
>  tools/perf/util/cpumap.h           |  5 ++++-
>  tools/perf/util/evlist.c           |  4 ++--
>  tools/perf/util/evsel.c            |  1 +
>  tools/perf/util/parse-events.c     |  5 ++++-
>  tools/perf/util/python.c           |  2 +-
>  tools/perf/util/record.c           |  4 ++--
>  tools/perf/util/session.c          |  2 +-
>  tools/perf/util/svghelper.c        |  2 +-
>  13 files changed, 42 insertions(+), 15 deletions(-)
> 
> diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
> index e2a432b67d52..86d17d2e9e50 100644
> --- a/tools/perf/tests/code-reading.c
> +++ b/tools/perf/tests/code-reading.c
> @@ -545,7 +545,7 @@ out_err:
>  	if (evlist) {
>  		perf_evlist__delete(evlist);
>  	} else {
> -		cpu_map__delete(cpus);
> +		cpu_map__put(cpus);
>  		thread_map__delete(threads);
>  	}
>  	machines__destroy_kernel_maps(&machines);
> diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
> index 5b171d1e338b..a330235cefc0 100644
> --- a/tools/perf/tests/keep-tracking.c
> +++ b/tools/perf/tests/keep-tracking.c
> @@ -144,7 +144,7 @@ out_err:
>  		perf_evlist__disable(evlist);
>  		perf_evlist__delete(evlist);
>  	} else {
> -		cpu_map__delete(cpus);
> +		cpu_map__put(cpus);
>  		thread_map__delete(threads);
>  	}
>  
> diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
> index 5855cf471210..5a9ef5833452 100644
> --- a/tools/perf/tests/mmap-basic.c
> +++ b/tools/perf/tests/mmap-basic.c
> @@ -140,7 +140,7 @@ out_delete_evlist:
>  	cpus	= NULL;
>  	threads = NULL;
>  out_free_cpus:
> -	cpu_map__delete(cpus);
> +	cpu_map__put(cpus);
>  out_free_threads:
>  	thread_map__delete(threads);
>  	return err;
> diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
> index 0d31403ea593..1b06122beb76 100644
> --- a/tools/perf/tests/switch-tracking.c
> +++ b/tools/perf/tests/switch-tracking.c
> @@ -560,7 +560,7 @@ out:
>  		perf_evlist__disable(evlist);
>  		perf_evlist__delete(evlist);
>  	} else {
> -		cpu_map__delete(cpus);
> +		cpu_map__put(cpus);
>  		thread_map__delete(threads);
>  	}
>  
> diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
> index c4e55b71010c..60f4297ed233 100644
> --- a/tools/perf/util/cpumap.c
> +++ b/tools/perf/util/cpumap.c
> @@ -5,6 +5,7 @@
>  #include <assert.h>
>  #include <stdio.h>
>  #include <stdlib.h>
> +#include "asm/bug.h"
>  
>  static struct cpu_map *cpu_map__default_new(void)
>  {
> @@ -22,6 +23,7 @@ static struct cpu_map *cpu_map__default_new(void)
>  			cpus->map[i] = i;
>  
>  		cpus->nr = nr_cpus;
> +		cpus->refcnt = 1;
>  	}
>  
>  	return cpus;
> @@ -35,6 +37,7 @@ static struct cpu_map *cpu_map__trim_new(int nr_cpus, int *tmp_cpus)
>  	if (cpus != NULL) {
>  		cpus->nr = nr_cpus;
>  		memcpy(cpus->map, tmp_cpus, payload_size);
> +		cpus->refcnt = 1;
>  	}
>  
>  	return cpus;
> @@ -194,14 +197,30 @@ struct cpu_map *cpu_map__dummy_new(void)
>  	if (cpus != NULL) {
>  		cpus->nr = 1;
>  		cpus->map[0] = -1;
> +		cpus->refcnt = 1;
>  	}
>  
>  	return cpus;
>  }
>  
> -void cpu_map__delete(struct cpu_map *map)
> +static void cpu_map__delete(struct cpu_map *map)
>  {
> -	free(map);
> +	if (map) {
> +		WARN_ONCE(map->refcnt != 0, "cpu map refcnt disbalanced\n");
> +		free(map);
> +	}
> +}
> +
> +struct cpu_map *cpu_map__get(struct cpu_map *map)
> +{
> +	map->refcnt++;
> +	return map;
> +}
> +
> +void cpu_map__put(struct cpu_map *map)
> +{
> +	if (map && --map->refcnt == 0)
> +		cpu_map__delete(map);
>  }
>  
>  int cpu_map__get_socket(struct cpu_map *map, int idx)
> @@ -263,6 +282,7 @@ static int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
>  	/* ensure we process id in increasing order */
>  	qsort(c->map, c->nr, sizeof(int), cmp_ids);
>  
> +	c->refcnt = 1;
>  	*res = c;
>  	return 0;
>  }
> diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
> index 61a654849002..19fe50b29375 100644
> --- a/tools/perf/util/cpumap.h
> +++ b/tools/perf/util/cpumap.h
> @@ -8,13 +8,13 @@
>  #include "util/debug.h"
>  
>  struct cpu_map {
> +	int refcnt;
>  	int nr;
>  	int map[];
>  };
>  
>  struct cpu_map *cpu_map__new(const char *cpu_list);
>  struct cpu_map *cpu_map__dummy_new(void);
> -void cpu_map__delete(struct cpu_map *map);
>  struct cpu_map *cpu_map__read(FILE *file);
>  size_t cpu_map__fprintf(struct cpu_map *map, FILE *fp);
>  int cpu_map__get_socket(struct cpu_map *map, int idx);
> @@ -22,6 +22,9 @@ int cpu_map__get_core(struct cpu_map *map, int idx);
>  int cpu_map__build_socket_map(struct cpu_map *cpus, struct cpu_map **sockp);
>  int cpu_map__build_core_map(struct cpu_map *cpus, struct cpu_map **corep);
>  
> +struct cpu_map *cpu_map__get(struct cpu_map *map);
> +void cpu_map__put(struct cpu_map *map);
> +
>  static inline int cpu_map__socket(struct cpu_map *sock, int s)
>  {
>  	if (!sock || s > sock->nr || s < 0)
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index dc1dc2c181ef..6b895de1144d 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -114,7 +114,7 @@ void perf_evlist__delete(struct perf_evlist *evlist)
>  {
>  	perf_evlist__munmap(evlist);
>  	perf_evlist__close(evlist);
> -	cpu_map__delete(evlist->cpus);
> +	cpu_map__put(evlist->cpus);
>  	thread_map__delete(evlist->threads);
>  	evlist->cpus = NULL;
>  	evlist->threads = NULL;
> @@ -1337,7 +1337,7 @@ static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist)
>  out:
>  	return err;
>  out_free_cpus:
> -	cpu_map__delete(evlist->cpus);
> +	cpu_map__put(evlist->cpus);
>  	evlist->cpus = NULL;
>  	goto out;
>  }
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index a3e36fc634dc..3bd5769dd7b9 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -902,6 +902,7 @@ void perf_evsel__exit(struct perf_evsel *evsel)
>  	perf_evsel__free_fd(evsel);
>  	perf_evsel__free_id(evsel);
>  	close_cgroup(evsel->cgrp);
> +	cpu_map__put(evsel->cpus);
>  	zfree(&evsel->group_name);
>  	zfree(&evsel->name);
>  	perf_evsel__object.fini(evsel);
> diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
> index 2a4d1ec02846..09f8d2357108 100644
> --- a/tools/perf/util/parse-events.c
> +++ b/tools/perf/util/parse-events.c
> @@ -17,6 +17,7 @@
>  #include "parse-events-flex.h"
>  #include "pmu.h"
>  #include "thread_map.h"
> +#include "cpumap.h"
>  #include "asm/bug.h"
>  
>  #define MAX_NAME_LEN 100
> @@ -285,7 +286,9 @@ __add_event(struct list_head *list, int *idx,
>  	if (!evsel)
>  		return NULL;
>  
> -	evsel->cpus = cpus;
> +	if (cpus)
> +		evsel->cpus = cpu_map__get(cpus);
> +
>  	if (name)
>  		evsel->name = strdup(name);
>  	list_add_tail(&evsel->node, list);
> diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
> index d906d0ad5d40..b106d56df240 100644
> --- a/tools/perf/util/python.c
> +++ b/tools/perf/util/python.c
> @@ -384,7 +384,7 @@ static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
>  
>  static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
>  {
> -	cpu_map__delete(pcpus->cpus);
> +	cpu_map__put(pcpus->cpus);
>  	pcpus->ob_type->tp_free((PyObject*)pcpus);
>  }
>  
> diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
> index d457c523a33d..1f7becbe5e18 100644
> --- a/tools/perf/util/record.c
> +++ b/tools/perf/util/record.c
> @@ -64,7 +64,7 @@ static bool perf_probe_api(setup_probe_fn_t fn)
>  	if (!cpus)
>  		return false;
>  	cpu = cpus->map[0];
> -	cpu_map__delete(cpus);
> +	cpu_map__put(cpus);
>  
>  	do {
>  		ret = perf_do_probe_api(fn, cpu, try[i++]);
> @@ -226,7 +226,7 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
>  		struct cpu_map *cpus = cpu_map__new(NULL);
>  
>  		cpu =  cpus ? cpus->map[0] : 0;
> -		cpu_map__delete(cpus);
> +		cpu_map__put(cpus);
>  	} else {
>  		cpu = evlist->cpus->map[0];
>  	}
> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> index 88d87bf3049f..c09f178cea63 100644
> --- a/tools/perf/util/session.c
> +++ b/tools/perf/util/session.c
> @@ -1838,7 +1838,7 @@ int perf_session__cpu_bitmap(struct perf_session *session,
>  	err = 0;
>  
>  out_delete_map:
> -	cpu_map__delete(map);
> +	cpu_map__put(map);
>  	return err;
>  }
>  
> diff --git a/tools/perf/util/svghelper.c b/tools/perf/util/svghelper.c
> index 283d3e73e2f2..eec6c1149f44 100644
> --- a/tools/perf/util/svghelper.c
> +++ b/tools/perf/util/svghelper.c
> @@ -748,7 +748,7 @@ static int str_to_bitmap(char *s, cpumask_t *b)
>  		set_bit(c, cpumask_bits(b));
>  	}
>  
> -	cpu_map__delete(m);
> +	cpu_map__put(m);
>  
>  	return ret;
>  }
> -- 
> 1.9.3

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 04/25] perf tools: Add reference counting for thread_map object
  2015-06-10 18:10 ` [PATCH 04/25] perf tools: Add reference counting for thread_map object Jiri Olsa
@ 2015-06-10 19:08   ` Arnaldo Carvalho de Melo
  2015-06-10 20:24     ` Jiri Olsa
  0 siblings, 1 reply; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 19:08 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 08:10:37PM +0200, Jiri Olsa escreveu:
> Adding refference counting for thread_map object, so
> it could be easily shared among other objects.
> 
> Using thread_map__put instead thread_map__delete and making
> thread_map__delete static.

Please use atomic.h, as was done recently for the 'map', 'dso' and
'thread' structs, but other than that, its fine.
 
> Link: http://lkml.kernel.org/n/tip-myadl53clbkjvzeqolwp95w0@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/tests/code-reading.c            |  2 +-
>  tools/perf/tests/keep-tracking.c           |  2 +-
>  tools/perf/tests/mmap-basic.c              |  2 +-
>  tools/perf/tests/mmap-thread-lookup.c      |  2 +-
>  tools/perf/tests/openat-syscall-all-cpus.c |  2 +-
>  tools/perf/tests/openat-syscall.c          |  2 +-
>  tools/perf/tests/switch-tracking.c         |  2 +-
>  tools/perf/util/evlist.c                   |  4 ++--
>  tools/perf/util/python.c                   |  2 +-
>  tools/perf/util/thread_map.c               | 28 ++++++++++++++++++++++++++--
>  tools/perf/util/thread_map.h               |  6 ++++--
>  11 files changed, 40 insertions(+), 14 deletions(-)
> 
> diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
> index 86d17d2e9e50..7dcd2c3d865f 100644
> --- a/tools/perf/tests/code-reading.c
> +++ b/tools/perf/tests/code-reading.c
> @@ -546,7 +546,7 @@ out_err:
>  		perf_evlist__delete(evlist);
>  	} else {
>  		cpu_map__put(cpus);
> -		thread_map__delete(threads);
> +		thread_map__put(threads);
>  	}
>  	machines__destroy_kernel_maps(&machines);
>  	machine__delete_threads(machine);
> diff --git a/tools/perf/tests/keep-tracking.c b/tools/perf/tests/keep-tracking.c
> index a330235cefc0..4d4b9837b630 100644
> --- a/tools/perf/tests/keep-tracking.c
> +++ b/tools/perf/tests/keep-tracking.c
> @@ -145,7 +145,7 @@ out_err:
>  		perf_evlist__delete(evlist);
>  	} else {
>  		cpu_map__put(cpus);
> -		thread_map__delete(threads);
> +		thread_map__put(threads);
>  	}
>  
>  	return err;
> diff --git a/tools/perf/tests/mmap-basic.c b/tools/perf/tests/mmap-basic.c
> index 5a9ef5833452..666b67a4df9d 100644
> --- a/tools/perf/tests/mmap-basic.c
> +++ b/tools/perf/tests/mmap-basic.c
> @@ -142,6 +142,6 @@ out_delete_evlist:
>  out_free_cpus:
>  	cpu_map__put(cpus);
>  out_free_threads:
> -	thread_map__delete(threads);
> +	thread_map__put(threads);
>  	return err;
>  }
> diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c
> index 264e215c0d36..412a41eb3f81 100644
> --- a/tools/perf/tests/mmap-thread-lookup.c
> +++ b/tools/perf/tests/mmap-thread-lookup.c
> @@ -143,7 +143,7 @@ static int synth_process(struct machine *machine)
>  						perf_event__process,
>  						machine, 0);
>  
> -	thread_map__delete(map);
> +	thread_map__put(map);
>  	return err;
>  }
>  
> diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
> index e34dfdf96b5a..8801983a38f0 100644
> --- a/tools/perf/tests/openat-syscall-all-cpus.c
> +++ b/tools/perf/tests/openat-syscall-all-cpus.c
> @@ -110,6 +110,6 @@ out_close_fd:
>  out_evsel_delete:
>  	perf_evsel__delete(evsel);
>  out_thread_map_delete:
> -	thread_map__delete(threads);
> +	thread_map__put(threads);
>  	return err;
>  }
> diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
> index 9f9491bb8e48..bdfa1f446681 100644
> --- a/tools/perf/tests/openat-syscall.c
> +++ b/tools/perf/tests/openat-syscall.c
> @@ -56,6 +56,6 @@ out_close_fd:
>  out_evsel_delete:
>  	perf_evsel__delete(evsel);
>  out_thread_map_delete:
> -	thread_map__delete(threads);
> +	thread_map__put(threads);
>  	return err;
>  }
> diff --git a/tools/perf/tests/switch-tracking.c b/tools/perf/tests/switch-tracking.c
> index 1b06122beb76..e698742d4fec 100644
> --- a/tools/perf/tests/switch-tracking.c
> +++ b/tools/perf/tests/switch-tracking.c
> @@ -561,7 +561,7 @@ out:
>  		perf_evlist__delete(evlist);
>  	} else {
>  		cpu_map__put(cpus);
> -		thread_map__delete(threads);
> +		thread_map__put(threads);
>  	}
>  
>  	return err;
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index 6b895de1144d..493675cfa90c 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -115,7 +115,7 @@ void perf_evlist__delete(struct perf_evlist *evlist)
>  	perf_evlist__munmap(evlist);
>  	perf_evlist__close(evlist);
>  	cpu_map__put(evlist->cpus);
> -	thread_map__delete(evlist->threads);
> +	thread_map__put(evlist->threads);
>  	evlist->cpus = NULL;
>  	evlist->threads = NULL;
>  	perf_evlist__purge(evlist);
> @@ -1104,7 +1104,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
>  	return 0;
>  
>  out_delete_threads:
> -	thread_map__delete(evlist->threads);
> +	thread_map__put(evlist->threads);
>  	evlist->threads = NULL;
>  	return -1;
>  }
> diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
> index b106d56df240..626422eda727 100644
> --- a/tools/perf/util/python.c
> +++ b/tools/perf/util/python.c
> @@ -453,7 +453,7 @@ static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
>  
>  static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
>  {
> -	thread_map__delete(pthreads->threads);
> +	thread_map__put(pthreads->threads);
>  	pthreads->ob_type->tp_free((PyObject*)pthreads);
>  }
>  
> diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
> index f93b9734735b..04bc15e339dd 100644
> --- a/tools/perf/util/thread_map.c
> +++ b/tools/perf/util/thread_map.c
> @@ -8,6 +8,7 @@
>  #include <unistd.h>
>  #include "strlist.h"
>  #include <string.h>
> +#include "asm/bug.h"
>  #include "thread_map.h"
>  #include "util.h"
>  
> @@ -38,6 +39,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid)
>  		for (i = 0; i < items; i++)
>  			threads->map[i] = atoi(namelist[i]->d_name);
>  		threads->nr = items;
> +		threads->refcnt = 1;
>  	}
>  
>  	for (i=0; i<items; i++)
> @@ -54,6 +56,7 @@ struct thread_map *thread_map__new_by_tid(pid_t tid)
>  	if (threads != NULL) {
>  		threads->map[0] = tid;
>  		threads->nr	= 1;
> +		threads->refcnt = 1;
>  	}
>  
>  	return threads;
> @@ -75,6 +78,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
>  		goto out_free_threads;
>  
>  	threads->nr = 0;
> +	threads->refcnt = 1;
>  
>  	while (!readdir_r(proc, &dirent, &next) && next) {
>  		char *end;
> @@ -202,6 +206,8 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
>  
>  out:
>  	strlist__delete(slist);
> +	if (threads)
> +		threads->refcnt = 1;
>  	return threads;
>  
>  out_free_namelist:
> @@ -221,6 +227,7 @@ struct thread_map *thread_map__new_dummy(void)
>  	if (threads != NULL) {
>  		threads->map[0]	= -1;
>  		threads->nr	= 1;
> +		threads->refcnt = 1;
>  	}
>  	return threads;
>  }
> @@ -263,6 +270,8 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
>  		threads->nr		 = ntasks;
>  	}
>  out:
> +	if (threads)
> +		threads->refcnt = 1;
>  	return threads;
>  
>  out_free_threads:
> @@ -282,9 +291,24 @@ struct thread_map *thread_map__new_str(const char *pid, const char *tid,
>  	return thread_map__new_by_tid_str(tid);
>  }
>  
> -void thread_map__delete(struct thread_map *threads)
> +static void thread_map__delete(struct thread_map *threads)
>  {
> -	free(threads);
> +	if (threads) {
> +		WARN_ONCE(threads->refcnt != 0, "thread map refcnt disbalanced\n");
> +		free(threads);
> +	}
> +}
> +
> +struct thread_map *thread_map__get(struct thread_map *map)
> +{
> +	map->refcnt++;
> +	return map;
> +}
> +
> +void thread_map__put(struct thread_map *map)
> +{
> +	if (map && --map->refcnt == 0)
> +		thread_map__delete(map);
>  }
>  
>  size_t thread_map__fprintf(struct thread_map *threads, FILE *fp)
> diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h
> index 95313f43cc0f..dc02c259da36 100644
> --- a/tools/perf/util/thread_map.h
> +++ b/tools/perf/util/thread_map.h
> @@ -5,6 +5,7 @@
>  #include <stdio.h>
>  
>  struct thread_map {
> +	int refcnt;
>  	int nr;
>  	pid_t map[];
>  };
> @@ -15,11 +16,12 @@ struct thread_map *thread_map__new_by_tid(pid_t tid);
>  struct thread_map *thread_map__new_by_uid(uid_t uid);
>  struct thread_map *thread_map__new(pid_t pid, pid_t tid, uid_t uid);
>  
> +struct thread_map *thread_map__get(struct thread_map *map);
> +void thread_map__put(struct thread_map *map);
> +
>  struct thread_map *thread_map__new_str(const char *pid,
>  		const char *tid, uid_t uid);
>  
> -void thread_map__delete(struct thread_map *threads);
> -
>  size_t thread_map__fprintf(struct thread_map *threads, FILE *fp);
>  
>  static inline int thread_map__nr(struct thread_map *threads)
> -- 
> 1.9.3

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 06/25] perf tools: Propagate thread maps through the evlist
  2015-06-10 18:10 ` [PATCH 06/25] perf tools: Propagate thread " Jiri Olsa
@ 2015-06-10 19:09   ` Arnaldo Carvalho de Melo
  2015-06-10 20:25     ` Jiri Olsa
  0 siblings, 1 reply; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 19:09 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 08:10:39PM +0200, Jiri Olsa escreveu:
> Propagate evlist's thread_map object through all the
> evsel objects.
> 
> It'll be handy to access evsel's threads directly
> in following patches.

Handy in what way? I.e. I should know one example without having to look
at future patches ;-)

- Arnaldo
 
> Link: http://lkml.kernel.org/n/tip-6vc92bytyy2d6c5entm5s698@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/util/evlist.c | 4 +++-
>  tools/perf/util/evsel.c  | 1 +
>  tools/perf/util/evsel.h  | 1 +
>  3 files changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index 7cb579ca5629..f438881040f2 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -1100,7 +1100,9 @@ static int propagate_maps(struct perf_evlist *evlist, struct target *target)
>  		if (!evsel->cpus || target->cpu_list)
>  			evsel->cpus = cpu_map__get(evlist->cpus);
>  
> -		if (!evsel->cpus)
> +		evsel->threads = thread_map__get(evlist->threads);
> +
> +		if (!evsel->cpus || !evsel->threads)
>  			return -ENOMEM;
>  	}
>  
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index 3bd5769dd7b9..bd1c3b71e455 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -903,6 +903,7 @@ void perf_evsel__exit(struct perf_evsel *evsel)
>  	perf_evsel__free_id(evsel);
>  	close_cgroup(evsel->cgrp);
>  	cpu_map__put(evsel->cpus);
> +	thread_map__put(evsel->threads);
>  	zfree(&evsel->group_name);
>  	zfree(&evsel->name);
>  	perf_evsel__object.fini(evsel);
> diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
> index 21ec08247d47..d18572223b08 100644
> --- a/tools/perf/util/evsel.h
> +++ b/tools/perf/util/evsel.h
> @@ -82,6 +82,7 @@ struct perf_evsel {
>  	struct cgroup_sel	*cgrp;
>  	void			*handler;
>  	struct cpu_map		*cpus;
> +	struct thread_map	*threads;
>  	unsigned int		sample_size;
>  	int			id_pos;
>  	int			is_pos;
> -- 
> 1.9.3

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 05/25] perf tools: Propagate cpu maps through the evlist
  2015-06-10 18:10 ` [PATCH 05/25] perf tools: Propagate cpu maps through the evlist Jiri Olsa
@ 2015-06-10 19:10   ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 19:10 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 08:10:38PM +0200, Jiri Olsa escreveu:
> Propagate evlist's cpu_map object through all the evsel objects,
> while keeping already configured evsel->cpus.
> 
> It'll be handy to access evsel's cpus directly
> in following patches.
> 
> Link: http://lkml.kernel.org/n/tip-myadl53clbkjvzeqolwp95w0@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/util/evlist.c | 24 +++++++++++++++++++++++-
>  1 file changed, 23 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index 493675cfa90c..7cb579ca5629 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -1085,6 +1085,28 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
>  	return perf_evlist__mmap_ex(evlist, pages, overwrite, 0, false);
>  }
>  
> +static int propagate_maps(struct perf_evlist *evlist, struct target *target)
> +{
> +	struct perf_evsel *evsel;
> +
> +	evlist__for_each(evlist, evsel) {
> +		/*
> +		 * We already have cpus for evsel (via PMU sysfs) so
> +		 * keep it, if there's no target cpu list defined.
> +		 */

There was some discussion about this with Stephane, lost track, will try
to dig it... :-\

- Arnaldo

> +		if (evsel->cpus && target->cpu_list)
> +			cpu_map__put(evsel->cpus);
> +
> +		if (!evsel->cpus || target->cpu_list)
> +			evsel->cpus = cpu_map__get(evlist->cpus);
> +
> +		if (!evsel->cpus)
> +			return -ENOMEM;
> +	}
> +
> +	return 0;
> +}
> +
>  int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
>  {
>  	evlist->threads = thread_map__new_str(target->pid, target->tid,
> @@ -1101,7 +1123,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
>  	if (evlist->cpus == NULL)
>  		goto out_delete_threads;
>  
> -	return 0;
> +	return propagate_maps(evlist, target);
>  
>  out_delete_threads:
>  	thread_map__put(evlist->threads);
> -- 
> 1.9.3

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 15/25] perf stat: Move perf_evlist__(alloc|free)_stats into evlist object
  2015-06-10 18:10 ` [PATCH 15/25] perf stat: Move perf_evlist__(alloc|free)_stats into evlist object Jiri Olsa
@ 2015-06-10 19:13   ` Arnaldo Carvalho de Melo
  2015-06-10 20:25     ` Jiri Olsa
  0 siblings, 1 reply; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 19:13 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 08:10:48PM +0200, Jiri Olsa escreveu:
> Moving perf_evlist__(alloc|free)_stats into evsel object,
> so it could be used in following patches.

Can this go into the new counts.[ch] file too? As it is specific to
counting tools?

- Arnaldo
 
> Link: http://lkml.kernel.org/n/tip-8dwmf838kipxabe0vay8h0zn@git.kernel.org
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/builtin-stat.c | 32 --------------------------------
>  tools/perf/util/evlist.c  | 32 ++++++++++++++++++++++++++++++++
>  tools/perf/util/evlist.h  |  2 ++
>  3 files changed, 34 insertions(+), 32 deletions(-)
> 
> diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> index b15fc47aa673..5072ca809c23 100644
> --- a/tools/perf/builtin-stat.c
> +++ b/tools/perf/builtin-stat.c
> @@ -141,38 +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_stat__reset_stats(struct perf_evlist *evlist)
>  {
>  	struct perf_evsel *evsel;
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index f438881040f2..44d52a07223c 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -1651,3 +1651,35 @@ void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
>  
>  	tracking_evsel->tracking = true;
>  }
> +
> +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))
> +			goto out_free;
> +	}
> +
> +	return 0;
> +
> +out_free:
> +	perf_evlist__free_stats(evlist);
> +	return -1;
> +}
> +
> +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);
> +	}
> +}
> diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
> index 955bf31b7dd3..557083673bab 100644
> --- a/tools/perf/util/evlist.h
> +++ b/tools/perf/util/evlist.h
> @@ -288,4 +288,6 @@ void perf_evlist__to_front(struct perf_evlist *evlist,
>  void perf_evlist__set_tracking_event(struct perf_evlist *evlist,
>  				     struct perf_evsel *tracking_evsel);
>  
> +int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw);
> +void perf_evlist__free_stats(struct perf_evlist *evlist);
>  #endif /* __PERF_EVLIST_H */
> -- 
> 1.9.3

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 25/25] perf stat: Introduce --per-task option
  2015-06-10 18:44   ` David Ahern
  2015-06-10 18:54     ` Jiri Olsa
@ 2015-06-10 19:28     ` Arnaldo Carvalho de Melo
  1 sibling, 0 replies; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 19:28 UTC (permalink / raw)
  To: David Ahern
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 12:44:34PM -0600, David Ahern escreveu:
> On 6/10/15 12:10 PM, Jiri Olsa wrote:
> >Also woks under interval mode:
> >
> >   $ ./perf stat -e cycles,instructions --per-task -p 16431,16173 -I 1000
> >   #           time task                      counts unit events
> >        1.000085816 TASK-16173                     0      cycles
> >        1.000085816 TASK-16431         3,358,360,926      cycles
> >        3.375949851 TASK-16173                     0      instructions
> >        3.375949851 TASK-16431         3,414,532,317      instructions
> >
> 
> Why not print $comm-$pid versus TASK-$pid?

Agreed.

- Arnaldo

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 02/25] perf tools: Introduce xyarray__zero function
  2015-06-10 19:06   ` Arnaldo Carvalho de Melo
@ 2015-06-10 20:01     ` Jiri Olsa
  2015-06-10 20:17       ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 20:01 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, David Ahern,
	Ingo Molnar, Namhyung Kim, Peter Zijlstra, Stephane Eranian

On Wed, Jun 10, 2015 at 04:06:00PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 10, 2015 at 08:10:35PM +0200, Jiri Olsa escreveu:
> > To zero all the xyarray contents. It will be used
> > in following patches.
> 
> I guess I would prefer xyarray__memset(), similar semantics as
> 'memset()', but I did a quick look and this is used in the kernel in
> things like bitmap_zero() and wrappers to it have that semantic...
> 
> Interesting that we don't have anymore a bzero() like function, but
> then, looking at 'man bzero':
> 
> ----------------------------
> CONFORMING TO
> 
>        4.3BSD.   This  function  is  deprecated  (marked  as  LEGACY  in
> POSIX.1-2001): use memset(3) in new programs.  POSIX.1-2008 removes the
> specification of bzero().
> 
> -----------------------------
> 
> Guess we should use 'xyarray__memset()', ok?

hum, how about xyarray__reset ?

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 03/25] perf tools: Add reference counting for cpu_map object
  2015-06-10 19:07   ` Arnaldo Carvalho de Melo
@ 2015-06-10 20:07     ` Jiri Olsa
  0 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 20:07 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, David Ahern,
	Ingo Molnar, Namhyung Kim, Peter Zijlstra, Stephane Eranian

On Wed, Jun 10, 2015 at 04:07:46PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 10, 2015 at 08:10:36PM +0200, Jiri Olsa escreveu:
> > Adding refference counting for cpu_map object, so
> > it could be easily shared among other objects.
> > 
> > Using cpu_map__put instead cpu_map__delete and making
> > cpu_map__delete static.
> 
> Please use atomic.h, as was done recently for the 'map', 'dso' and
> 'thread' structs, but other than that, its fine.

ook,

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 02/25] perf tools: Introduce xyarray__zero function
  2015-06-10 20:01     ` Jiri Olsa
@ 2015-06-10 20:17       ` Arnaldo Carvalho de Melo
  0 siblings, 0 replies; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 20:17 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, David Ahern,
	Ingo Molnar, Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 10:01:38PM +0200, Jiri Olsa escreveu:
> On Wed, Jun 10, 2015 at 04:06:00PM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Wed, Jun 10, 2015 at 08:10:35PM +0200, Jiri Olsa escreveu:
> > > To zero all the xyarray contents. It will be used
> > > in following patches.

> > Guess we should use 'xyarray__memset()', ok?

> hum, how about xyarray__reset?

I am ok with it, its already used in many places:

[acme@zoo linux]$ find tools -name "*.[ch]" | xargs grep __reset | wc -l
60
[acme@zoo linux]$

- Arnaldo

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 21/25] perf stat: Move perf_stat initialization counter process code
  2015-06-10 18:47   ` David Ahern
@ 2015-06-10 20:21     ` Jiri Olsa
  0 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 20:21 UTC (permalink / raw)
  To: David Ahern
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, lkml, Adrian Hunter,
	Andi Kleen, Ingo Molnar, Namhyung Kim, Peter Zijlstra,
	Stephane Eranian

On Wed, Jun 10, 2015 at 12:47:02PM -0600, David Ahern wrote:
> On 6/10/15 12:10 PM, Jiri Olsa wrote:
> >diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
> >index efc4d420f12e..3ababdb83aad 100644
> >--- a/tools/perf/builtin-stat.c
> >+++ b/tools/perf/builtin-stat.c
> >@@ -290,6 +290,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()?
> 

right, thanks

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 13/25] perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into evsel object
  2015-06-10 18:49   ` Arnaldo Carvalho de Melo
@ 2015-06-10 20:21     ` Jiri Olsa
  0 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 20:21 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, David Ahern,
	Ingo Molnar, Namhyung Kim, Peter Zijlstra, Stephane Eranian

On Wed, Jun 10, 2015 at 03:49:25PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 10, 2015 at 08:10:46PM +0200, Jiri Olsa escreveu:
> > Moving perf_evsel__(alloc|free|reset)_stat_priv into evsel object,
> > so it could be used outside stat object in following patches.
>  
> > +++ b/tools/perf/util/evsel.c
>   
> > +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);
> > +}
> 
> Please move this to some 'stat' specific place, so that evsel.c has
> nothing that is tool specific, like references to 'struct perf_stat'.

ok, util/stat.c then

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 08/25] perf stat: Introduce perf_counts__(alloc|free|reset) functions
  2015-06-10 18:54   ` Arnaldo Carvalho de Melo
@ 2015-06-10 20:22     ` Jiri Olsa
  0 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 20:22 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, David Ahern,
	Ingo Molnar, Namhyung Kim, Peter Zijlstra, Stephane Eranian

On Wed, Jun 10, 2015 at 03:54:27PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 10, 2015 at 08:10:41PM +0200, Jiri Olsa escreveu:
> > Move 'struct perf_counts' allocation|free|reset code into
> > separate functions.
> > 
> > Link: http://lkml.kernel.org/n/tip-qu64zmm5zbpbkuybusnkg4gl@git.kernel.org
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> >  tools/perf/builtin-stat.c | 19 +++++++------------
> >  tools/perf/util/evsel.c   | 28 +++++++++++++++++++++++-----
> >  tools/perf/util/evsel.h   |  3 +++
> >  3 files changed, 33 insertions(+), 17 deletions(-)
> 
> But please do not move it to 'evsel.[ch]', i.e. you're introducing a new
> class, i.e. "perf_counts", you might as well put them in a separate
> file, i.e. tools/perf/util/counts.[ch].
> 
> And please rename perf_counts__alloc() to perf_counds__new(), ditto for
> __free() -> __delete(), 

ok

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 01/25] perf tools: Fix python code with missing stat dependency
  2015-06-10 18:55   ` Arnaldo Carvalho de Melo
@ 2015-06-10 20:23     ` Jiri Olsa
  2015-06-10 20:32       ` Arnaldo Carvalho de Melo
  0 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 20:23 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, David Ahern,
	Ingo Molnar, Namhyung Kim, Peter Zijlstra, Stephane Eranian

On Wed, Jun 10, 2015 at 03:55:45PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 10, 2015 at 08:10:34PM +0200, Jiri Olsa escreveu:
> > The evsel object now depends on stat object and breaks
> > python code because of missing stat object dependency.
> > Putting stat.c object into python object list.
> 
> Applied, but 'perf test python'  was Okaying me before and after this
> change, strange :-\

did you do 'make clean' ? there's not perfect dependency checking
for python binding building ;-)

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 04/25] perf tools: Add reference counting for thread_map object
  2015-06-10 19:08   ` Arnaldo Carvalho de Melo
@ 2015-06-10 20:24     ` Jiri Olsa
  0 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 20:24 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, David Ahern,
	Ingo Molnar, Namhyung Kim, Peter Zijlstra, Stephane Eranian

On Wed, Jun 10, 2015 at 04:08:25PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 10, 2015 at 08:10:37PM +0200, Jiri Olsa escreveu:
> > Adding refference counting for thread_map object, so
> > it could be easily shared among other objects.
> > 
> > Using thread_map__put instead thread_map__delete and making
> > thread_map__delete static.
> 
> Please use atomic.h, as was done recently for the 'map', 'dso' and
> 'thread' structs, but other than that, its fine.

ook

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 06/25] perf tools: Propagate thread maps through the evlist
  2015-06-10 19:09   ` Arnaldo Carvalho de Melo
@ 2015-06-10 20:25     ` Jiri Olsa
  2015-06-11 13:07       ` Namhyung Kim
  0 siblings, 1 reply; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 20:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, David Ahern,
	Ingo Molnar, Namhyung Kim, Peter Zijlstra, Stephane Eranian

On Wed, Jun 10, 2015 at 04:09:32PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 10, 2015 at 08:10:39PM +0200, Jiri Olsa escreveu:
> > Propagate evlist's thread_map object through all the
> > evsel objects.
> > 
> > It'll be handy to access evsel's threads directly
> > in following patches.
> 
> Handy in what way? I.e. I should know one example without having to look
> at future patches ;-)

there's no link to evlist which hold threads map now,
and it's not always available.. I'll update the changelog
in v2

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 15/25] perf stat: Move perf_evlist__(alloc|free)_stats into evlist object
  2015-06-10 19:13   ` Arnaldo Carvalho de Melo
@ 2015-06-10 20:25     ` Jiri Olsa
  0 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-10 20:25 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, David Ahern,
	Ingo Molnar, Namhyung Kim, Peter Zijlstra, Stephane Eranian

On Wed, Jun 10, 2015 at 04:13:52PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 10, 2015 at 08:10:48PM +0200, Jiri Olsa escreveu:
> > Moving perf_evlist__(alloc|free)_stats into evsel object,
> > so it could be used in following patches.
> 
> Can this go into the new counts.[ch] file too? As it is specific to
> counting tools?

ook

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 01/25] perf tools: Fix python code with missing stat dependency
  2015-06-10 20:23     ` Jiri Olsa
@ 2015-06-10 20:32       ` Arnaldo Carvalho de Melo
  2015-06-13 10:10         ` Jiri Olsa
  0 siblings, 1 reply; 54+ messages in thread
From: Arnaldo Carvalho de Melo @ 2015-06-10 20:32 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, David Ahern,
	Ingo Molnar, Namhyung Kim, Peter Zijlstra, Stephane Eranian

Em Wed, Jun 10, 2015 at 10:23:48PM +0200, Jiri Olsa escreveu:
> On Wed, Jun 10, 2015 at 03:55:45PM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Wed, Jun 10, 2015 at 08:10:34PM +0200, Jiri Olsa escreveu:
> > > The evsel object now depends on stat object and breaks
> > > python code because of missing stat object dependency.
> > > Putting stat.c object into python object list.
> > 
> > Applied, but 'perf test python'  was Okaying me before and after this
> > change, strange :-\
> 
> did you do 'make clean' ? there's not perfect dependency checking
> for python binding building ;-)

I guess I did that, yes ;-)

But to make sure:

[acme@zoo linux]$ type perf
perf is /home/acme/bin/perf
[acme@zoo linux]$ rm -f ~/bin/perf
[acme@zoo linux]$ type perf
bash: type: perf: not found
[acme@zoo linux]$ rm -rf /tmp/build/perf
[acme@zoo linux]$ perf
bash: perf: command not found...
Install package 'perf' to provide command 'perf'? [N/y] n
[acme@zoo linux]$ mkdir -p /tmp/build/perf
[acme@zoo linux]$ alias m
alias m='time make O=/tmp/build/perf -C tools/perf install-bin'
[acme@zoo linux]$ m
make: Entering directory '/home/git/linux/tools/perf'
  BUILD:   Doing 'make -j4' parallel build

Auto-detecting system features:
...                         dwarf: [ on  ]
...                         glibc: [ on  ]
...                          gtk2: [ on  ]
...                      libaudit: [ on  ]
...                        libbfd: [ on  ]
...                        libelf: [ on  ]
...                       libnuma: [ on  ]
...                       libperl: [ on  ]
...                     libpython: [ on  ]
...                      libslang: [ on  ]
...                     libunwind: [ on  ]
...            libdw-dwarf-unwind: [ on  ]
...                          zlib: [ on  ]
...                          lzma: [ on  ]

  MKDIR    /tmp/build/perf/util/
  CC       /tmp/build/perf/util/abspath.o
  MKDIR    /tmp/build/perf/fd/
  CC       /tmp/build/perf/fd/array.o
  CC       /tmp/build/perf/event-parse.o
<SNIP>
  INSTALL  perl-scripts
  INSTALL  python-scripts
  INSTALL  perf_completion-script
make: Leaving directory '/home/git/linux/tools/perf'

real	0m9.785s
user	0m15.868s
sys	0m5.756s
[acme@zoo linux]$

[acme@zoo linux]$ perf test python
17: Try 'import perf' in python, checking link problems      : Ok
[acme@zoo linux]$ su -
Password: 
[root@zoo ~]# perf test python
17: Try 'import perf' in python, checking link problems      : Ok
[root@zoo ~]# type perf
perf is hashed (/root/bin/perf)
[root@zoo ~]# ls -la ~/bin/perf
lrwxrwxrwx. 1 root root 19 Apr 29 15:58 /root/bin/perf -> /home/acme/bin/perf
[root@zoo ~]# 

So, it still works well, without your patch.

- Arnaldo

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 06/25] perf tools: Propagate thread maps through the evlist
  2015-06-10 20:25     ` Jiri Olsa
@ 2015-06-11 13:07       ` Namhyung Kim
  2015-06-12 20:13         ` Jiri Olsa
  0 siblings, 1 reply; 54+ messages in thread
From: Namhyung Kim @ 2015-06-11 13:07 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: Arnaldo Carvalho de Melo, Jiri Olsa, lkml, Adrian Hunter,
	Andi Kleen, David Ahern, Ingo Molnar, Peter Zijlstra,
	Stephane Eranian

Hi Jiri,

On Wed, Jun 10, 2015 at 10:25:13PM +0200, Jiri Olsa wrote:
> On Wed, Jun 10, 2015 at 04:09:32PM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Wed, Jun 10, 2015 at 08:10:39PM +0200, Jiri Olsa escreveu:
> > > Propagate evlist's thread_map object through all the
> > > evsel objects.
> > > 
> > > It'll be handy to access evsel's threads directly
> > > in following patches.
> > 
> > Handy in what way? I.e. I should know one example without having to look
> > at future patches ;-)
> 
> there's no link to evlist which hold threads map now,
> and it's not always available.. I'll update the changelog
> in v2

What about adding a link to evlist in evsel then?

Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 06/25] perf tools: Propagate thread maps through the evlist
  2015-06-11 13:07       ` Namhyung Kim
@ 2015-06-12 20:13         ` Jiri Olsa
  0 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-12 20:13 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: Arnaldo Carvalho de Melo, Jiri Olsa, lkml, Adrian Hunter,
	Andi Kleen, David Ahern, Ingo Molnar, Peter Zijlstra,
	Stephane Eranian

On Thu, Jun 11, 2015 at 10:07:40PM +0900, Namhyung Kim wrote:
> Hi Jiri,
> 
> On Wed, Jun 10, 2015 at 10:25:13PM +0200, Jiri Olsa wrote:
> > On Wed, Jun 10, 2015 at 04:09:32PM -0300, Arnaldo Carvalho de Melo wrote:
> > > Em Wed, Jun 10, 2015 at 08:10:39PM +0200, Jiri Olsa escreveu:
> > > > Propagate evlist's thread_map object through all the
> > > > evsel objects.
> > > > 
> > > > It'll be handy to access evsel's threads directly
> > > > in following patches.
> > > 
> > > Handy in what way? I.e. I should know one example without having to look
> > > at future patches ;-)
> > 
> > there's no link to evlist which hold threads map now,
> > and it's not always available.. I'll update the changelog
> > in v2
> 
> What about adding a link to evlist in evsel then?

I guess thats possiuble, but we already have it for cpu map in evsel,
so I wanted to stay consistent with thread map.. and it's just pointer
with extra refcnt increased

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH 01/25] perf tools: Fix python code with missing stat dependency
  2015-06-10 20:32       ` Arnaldo Carvalho de Melo
@ 2015-06-13 10:10         ` Jiri Olsa
  0 siblings, 0 replies; 54+ messages in thread
From: Jiri Olsa @ 2015-06-13 10:10 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: Jiri Olsa, lkml, Adrian Hunter, Andi Kleen, David Ahern,
	Ingo Molnar, Namhyung Kim, Peter Zijlstra, Stephane Eranian

On Wed, Jun 10, 2015 at 05:32:19PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 10, 2015 at 10:23:48PM +0200, Jiri Olsa escreveu:
> > On Wed, Jun 10, 2015 at 03:55:45PM -0300, Arnaldo Carvalho de Melo wrote:
> > > Em Wed, Jun 10, 2015 at 08:10:34PM +0200, Jiri Olsa escreveu:
> > > > The evsel object now depends on stat object and breaks
> > > > python code because of missing stat object dependency.
> > > > Putting stat.c object into python object list.
> > > 
> > > Applied, but 'perf test python'  was Okaying me before and after this
> > > change, strange :-\
> > 
> > did you do 'make clean' ? there's not perfect dependency checking
> > for python binding building ;-)
> 
> I guess I did that, yes ;-)

ugh, the new version is all stat specific.. so no evsel dependency
sry for the noise ;-)

jirka

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2015-06-13 10:11 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-10 18:10 [RFC/PATCH 00/25] perf stat: Introduce --per-task option Jiri Olsa
2015-06-10 18:10 ` [PATCH 01/25] perf tools: Fix python code with missing stat dependency Jiri Olsa
2015-06-10 18:55   ` Arnaldo Carvalho de Melo
2015-06-10 20:23     ` Jiri Olsa
2015-06-10 20:32       ` Arnaldo Carvalho de Melo
2015-06-13 10:10         ` Jiri Olsa
2015-06-10 18:10 ` [PATCH 02/25] perf tools: Introduce xyarray__zero function Jiri Olsa
2015-06-10 19:06   ` Arnaldo Carvalho de Melo
2015-06-10 20:01     ` Jiri Olsa
2015-06-10 20:17       ` Arnaldo Carvalho de Melo
2015-06-10 18:10 ` [PATCH 03/25] perf tools: Add reference counting for cpu_map object Jiri Olsa
2015-06-10 19:07   ` Arnaldo Carvalho de Melo
2015-06-10 20:07     ` Jiri Olsa
2015-06-10 18:10 ` [PATCH 04/25] perf tools: Add reference counting for thread_map object Jiri Olsa
2015-06-10 19:08   ` Arnaldo Carvalho de Melo
2015-06-10 20:24     ` Jiri Olsa
2015-06-10 18:10 ` [PATCH 05/25] perf tools: Propagate cpu maps through the evlist Jiri Olsa
2015-06-10 19:10   ` Arnaldo Carvalho de Melo
2015-06-10 18:10 ` [PATCH 06/25] perf tools: Propagate thread " Jiri Olsa
2015-06-10 19:09   ` Arnaldo Carvalho de Melo
2015-06-10 20:25     ` Jiri Olsa
2015-06-11 13:07       ` Namhyung Kim
2015-06-12 20:13         ` Jiri Olsa
2015-06-10 18:10 ` [PATCH 07/25] perf tools: Make perf_evsel__(nr_)cpus generic Jiri Olsa
2015-06-10 18:10 ` [PATCH 08/25] perf stat: Introduce perf_counts__(alloc|free|reset) functions Jiri Olsa
2015-06-10 18:54   ` Arnaldo Carvalho de Melo
2015-06-10 20:22     ` Jiri Olsa
2015-06-10 18:10 ` [PATCH 09/25] perf stat: Introduce perf_counts function Jiri Olsa
2015-06-10 18:10 ` [PATCH 10/25] perf stat: Use xyarray for cpu evsel counts Jiri Olsa
2015-06-10 18:10 ` [PATCH 11/25] perf stat: Make stats work over the thread dimension Jiri Olsa
2015-06-10 18:10 ` [PATCH 12/25] perf stat: Rename struct perf_counts::cpu member to values Jiri Olsa
2015-06-10 18:10 ` [PATCH 13/25] perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into evsel object Jiri Olsa
2015-06-10 18:49   ` Arnaldo Carvalho de Melo
2015-06-10 20:21     ` Jiri Olsa
2015-06-10 18:10 ` [PATCH 14/25] perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts " Jiri Olsa
2015-06-10 18:10 ` [PATCH 15/25] perf stat: Move perf_evlist__(alloc|free)_stats into evlist object Jiri Olsa
2015-06-10 19:13   ` Arnaldo Carvalho de Melo
2015-06-10 20:25     ` Jiri Olsa
2015-06-10 18:10 ` [PATCH 16/25] perf stat: Introduce perf_evsel__alloc_stats function Jiri Olsa
2015-06-10 18:10 ` [PATCH 17/25] perf stat: Introduce perf_evsel__read function Jiri Olsa
2015-06-10 18:10 ` [PATCH 18/25] perf stat: Introduce read_counters function Jiri Olsa
2015-06-10 18:10 ` [PATCH 19/25] perf stat: Separate counters reading and processing Jiri Olsa
2015-06-10 18:10 ` [PATCH 20/25] perf stat: Move zero_per_pkg into counter process code Jiri Olsa
2015-06-10 18:10 ` [PATCH 21/25] perf stat: Move perf_stat initialization " Jiri Olsa
2015-06-10 18:47   ` David Ahern
2015-06-10 20:21     ` Jiri Olsa
2015-06-10 18:10 ` [PATCH 22/25] perf stat: Remove perf_evsel__read_cb function Jiri Olsa
2015-06-10 18:10 ` [PATCH 23/25] perf stat: Rename print_interval to process_interval Jiri Olsa
2015-06-10 18:10 ` [PATCH 24/25] perf stat: Introduce print_counters function Jiri Olsa
2015-06-10 18:10 ` [PATCH 25/25] perf stat: Introduce --per-task option Jiri Olsa
2015-06-10 18:44   ` David Ahern
2015-06-10 18:54     ` Jiri Olsa
2015-06-10 19:28     ` Arnaldo Carvalho de Melo
2015-06-10 18:16 ` [RFC/PATCH 00/25] " Jiri Olsa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.