$EXTINDEX_DIR/description missing
 help / color / mirror / Atom feed
* [Buildroot] [PATCH] package/perl: Fix typos in HOSTCC specification
From: Peter Korsgaard @ 2015-06-22 22:39 UTC (permalink / raw)
  To: buildroot
In-Reply-To: <1435011012-23666-1-git-send-email-trisk@omniti.com>

>>>>> "Albert" == Albert Lee <trisk@omniti.com> writes:

 > Signed-off-by: Albert Lee <trisk@omniti.com>

Committed, thanks.

-- 
Bye, Peter Korsgaard

^ permalink raw reply

* [PATCH 27/27] perf stat: Introduce --per-thread option
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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

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

  $ perf stat  -e cycles,instructions --per-thread -p 30190,30242
  ^C
   Performance counter stats for process id '30190,30242':

               cat-30190                     0      cycles
               yes-30242         3,842,525,421      cycles
               cat-30190                     0      instructions
               yes-30242        10,370,817,010      instructions

         1.143155657 seconds time elapsed

Also works under interval mode:

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

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

  $ perf stat  -e cycles --per-thread  -I 1000 ls
  The --per-thread option is only available when monitoring via -p -t options.
      -p, --pid <pid>       stat events on existing process id
      -t, --tid <tid>       stat events on existing thread id

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

diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt
index 04e150d83e7d..47469abdcc1c 100644
--- a/tools/perf/Documentation/perf-stat.txt
+++ b/tools/perf/Documentation/perf-stat.txt
@@ -144,6 +144,10 @@ is a useful mode to detect imbalance between physical cores.  To enable this mod
 use --per-core in addition to -a. (system-wide).  The output includes the
 core number and the number of online logical processors on that physical processor.
 
+--per-thread::
+Aggregate counts per monitored threads, when monitoring threads (-t option)
+or processes (-p option).
+
 -D msecs::
 --delay msecs::
 After starting the program, wait msecs before measuring. This is useful to
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 56dc8881cb05..64e67b27528d 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -231,6 +231,7 @@ process_counter_values(struct perf_evsel *evsel, int cpu, int thread,
 		count = &zero;
 
 	switch (aggr_mode) {
+	case AGGR_THREAD:
 	case AGGR_CORE:
 	case AGGR_SOCKET:
 	case AGGR_NONE:
@@ -602,6 +603,14 @@ 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_THREAD:
+		fprintf(output, "%*s-%*d%s",
+			csv_output ? 0 : 16,
+			thread_map__comm(evsel->threads, id),
+			csv_output ? 0 : -8,
+			thread_map__pid(evsel->threads, id),
+			csv_sep);
+		break;
 	case AGGR_GLOBAL:
 	default:
 		break;
@@ -750,6 +759,40 @@ static void print_aggr(char *prefix)
 	}
 }
 
+static void print_aggr_thread(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
@@ -876,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_THREAD:
+			fprintf(output, "#           time             comm-pid                  counts %*s events\n", unit_width, "unit");
+			break;
 		case AGGR_GLOBAL:
 		default:
 			fprintf(output, "#           time             counts %*s events\n", unit_width, "unit");
@@ -944,6 +990,10 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)
 	case AGGR_SOCKET:
 		print_aggr(prefix);
 		break;
+	case AGGR_THREAD:
+		evlist__for_each(evsel_list, counter)
+			print_aggr_thread(counter, prefix);
+		break;
 	case AGGR_GLOBAL:
 		evlist__for_each(evsel_list, counter)
 			print_counter_aggr(counter, prefix);
@@ -1031,6 +1081,7 @@ static int perf_stat_init_aggr_mode(void)
 		break;
 	case AGGR_NONE:
 	case AGGR_GLOBAL:
+	case AGGR_THREAD:
 	default:
 		break;
 	}
@@ -1255,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-thread", &aggr_mode,
+		     "aggregate counts per thread", AGGR_THREAD),
 	OPT_UINTEGER('D', "delay", &initial_delay,
 		     "ms to wait before starting measurement after program start"),
 	OPT_END()
@@ -1346,8 +1399,19 @@ 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) &&
+	if ((aggr_mode == AGGR_THREAD) && !target__has_task(&target)) {
+		fprintf(stderr, "The --per-thread option is only available "
+			"when monitoring via -p -t options.\n");
+		parse_options_usage(NULL, options, "p", 1);
+		parse_options_usage(NULL, options, "t", 1);
+		goto out;
+	}
+
+	/*
+	 * no_aggr, cgroup are for system-wide only
+	 * --per-thread is aggregated per thread, we dont mix it with cpu mode
+	 */
+	if (((aggr_mode != AGGR_GLOBAL && aggr_mode != AGGR_THREAD) || 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 9f05c571befe..1cfbe0a980ac 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -30,6 +30,7 @@ enum aggr_mode {
 	AGGR_GLOBAL,
 	AGGR_SOCKET,
 	AGGR_CORE,
+	AGGR_THREAD,
 };
 
 struct perf_counts_values {
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [Buildroot] [git commit] package/perl: Fix typos in HOSTCC specification
From: Peter Korsgaard @ 2015-06-22 22:39 UTC (permalink / raw)
  To: buildroot

commit: http://git.buildroot.net/buildroot/commit/?id=f2aabda7d05a9af9dba81e976042bafdd2bf5d69
branch: http://git.buildroot.net/buildroot/commit/?id=refs/heads/master

Signed-off-by: Albert Lee <trisk@omniti.com>
Acked-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
Signed-off-by: Peter Korsgaard <peter@korsgaard.com>
---
 package/perl/perl.mk |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/package/perl/perl.mk b/package/perl/perl.mk
index 93efc57..c3569a9 100644
--- a/package/perl/perl.mk
+++ b/package/perl/perl.mk
@@ -75,7 +75,7 @@ PERL_CONF_OPTS += --only-mod=$(subst $(space),$(comma),$(PERL_MODULES))
 endif
 
 define PERL_CONFIGURE_CMDS
-	(cd $(@D); HOSTCC='$(HOSTCC_NOCACHE)' ./configure $(PERL_CONF_OPTS))
+	(cd $(@D); HOSTCC='$(HOSTCC_NOCCACHE)' ./configure $(PERL_CONF_OPTS))
 	$(SED) 's/UNKNOWN-/Buildroot $(BR2_VERSION_FULL) /' $(@D)/patchlevel.h
 endef
 
@@ -101,7 +101,7 @@ HOST_PERL_CONF_OPTS = \
 	-Dcc="$(HOSTCC)"
 
 define HOST_PERL_CONFIGURE_CMDS
-	(cd $(@D); HOSTCC='$(HOSTCC_NOCACHE)' ./Configure $(HOST_PERL_CONF_OPTS))
+	(cd $(@D); HOSTCC='$(HOSTCC_NOCCACHE)' ./Configure $(HOST_PERL_CONF_OPTS))
 endef
 
 define HOST_PERL_BUILD_CMDS

^ permalink raw reply related

* [PATCH 25/27] perf stat: Using init_stats instead of memset
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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

Reported-by: David Ahern <dsahern@gmail.com>
Link: http://lkml.kernel.org/n/tip-secivjava21t7921lkpy0pfj@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-stat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index aa706fca410e..39a97ade2cf3 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -284,7 +284,7 @@ static int process_counter(struct perf_evsel *counter)
 	int i, ret;
 
 	aggr->val = aggr->ena = aggr->run = 0;
-	memset(ps->res_stats, 0, sizeof(ps->res_stats));
+	init_stats(ps->res_stats);
 
 	if (counter->per_pkg)
 		zero_per_pkg(counter);
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 2/2] x86/mm/pat, drivers/media/ivtv: replace WARN() with pr_warn()
From: Luis R. Rodriguez @ 2015-06-22 22:31 UTC (permalink / raw)
  To: bp, mchehab, dledford
  Cc: mingo, fengguang.wu, linux-media, linux-rdma, linux-kernel,
	Luis R. Rodriguez
In-Reply-To: <1435012318-381-1-git-send-email-mcgrof@do-not-panic.com>

From: "Luis R. Rodriguez" <mcgrof@suse.com>

On built-in kernels this will always splat. Fix that.

Reported-by: Fengguang Wu <fengguang.wu@intel.com> [0-day test robot]
Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
---
 drivers/media/pci/ivtv/ivtvfb.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c
index 4cb365d..6f0c364 100644
--- a/drivers/media/pci/ivtv/ivtvfb.c
+++ b/drivers/media/pci/ivtv/ivtvfb.c
@@ -38,6 +38,8 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fb.h>
@@ -1266,8 +1268,8 @@ static int __init ivtvfb_init(void)
 	int err;
 
 #ifdef CONFIG_X86_64
-	if (WARN(pat_enabled(),
-		 "ivtvfb needs PAT disabled, boot with nopat kernel parameter\n")) {
+	if (pat_enabled()) {
+		pr_warn("ivtvfb needs PAT disabled, boot with nopat kernel parameter\n");
 		return -ENODEV;
 	}
 #endif
-- 
2.3.2.209.gd67f9d5.dirty

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH RESEND V3] spmi: add command tracepoints for SPMI
From: Ankit Gupta @ 2015-06-22 22:38 UTC (permalink / raw)
  To: linux-arm-kernel

Add tracepoints to retrieve information about read, write
and non-data commands. For performance measurement support
tracepoints are added at the beginning and at the end of
transfers. Following is a list showing the new tracepoint
events. The "cmd" parameter here represents the opcode, SID,
and full 16-bit address.

spmi_write_begin: cmd and data buffer.
spmi_write_end  : cmd and return value.
spmi_read_begin : cmd.
spmi_read_end   : cmd, return value and data buffer.
spmi_cmd        : cmd.

The reason that cmd appears at both the beginning and at
the end event is that SPMI drivers can request commands
concurrently. cmd helps in matching the corresponding
events.

SPMI tracepoints can be enabled like:

echo 1 >/sys/kernel/debug/tracing/events/spmi/enable

and will dump messages that can be viewed in
/sys/kernel/debug/tracing/trace that look like:

... spmi_read_begin: opc=56 sid=00 addr=0x0000
... spmi_read_end: opc=56 sid=00 addr=0x0000 ret=0 len=02 buf=0x[01-40]
... spmi_write_begin: opc=48 sid=00 addr=0x0000 len=3 buf=0x[ff-ff-ff]

Suggested-by: Sagar Dharia <sdharia@codeaurora.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Gilad Avidov <gavidov@codeaurora.org>
Signed-off-by: Ankit Gupta <ankgupta@codeaurora.org>

---
Changes since v2:
- use full names in events: wr->write, rd->read, beg->begin.
- Edited the commit text to reflect full names of event.
---
Changes since V1:
- Change from ':' to "=" in printk in spmi.h.
- Added extra line between declaration and Code in spmi.c.
- Added use and example of spmi dump message in commit text.
---
 drivers/spmi/spmi.c         |  22 +++++++-
 include/trace/events/spmi.h | 135 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 154 insertions(+), 3 deletions(-)
 create mode 100644 include/trace/events/spmi.h

diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 1d92f51..36fe010 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -21,6 +21,8 @@
 #include <linux/pm_runtime.h>
 
 #include <dt-bindings/spmi/spmi.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/spmi.h>
 
 static DEFINE_IDA(ctrl_ida);
 
@@ -95,28 +97,42 @@ EXPORT_SYMBOL_GPL(spmi_device_remove);
 static inline int
 spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid)
 {
+	int ret;
+
 	if (!ctrl || !ctrl->cmd || ctrl->dev.type != &spmi_ctrl_type)
 		return -EINVAL;
 
-	return ctrl->cmd(ctrl, opcode, sid);
+	ret = ctrl->cmd(ctrl, opcode, sid);
+	trace_spmi_cmd(opcode, sid, ret);
+	return ret;
 }
 
 static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode,
 				u8 sid, u16 addr, u8 *buf, size_t len)
 {
+	int ret;
+
 	if (!ctrl || !ctrl->read_cmd || ctrl->dev.type != &spmi_ctrl_type)
 		return -EINVAL;
 
-	return ctrl->read_cmd(ctrl, opcode, sid, addr, buf, len);
+	trace_spmi_read_begin(opcode, sid, addr);
+	ret = ctrl->read_cmd(ctrl, opcode, sid, addr, buf, len);
+	trace_spmi_read_end(opcode, sid, addr, ret, len, buf);
+	return ret;
 }
 
 static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode,
 				 u8 sid, u16 addr, const u8 *buf, size_t len)
 {
+	int ret;
+
 	if (!ctrl || !ctrl->write_cmd || ctrl->dev.type != &spmi_ctrl_type)
 		return -EINVAL;
 
-	return ctrl->write_cmd(ctrl, opcode, sid, addr, buf, len);
+	trace_spmi_write_begin(opcode, sid, addr, len, buf);
+	ret = ctrl->write_cmd(ctrl, opcode, sid, addr, buf, len);
+	trace_spmi_write_end(opcode, sid, addr, ret);
+	return ret;
 }
 
 /**
diff --git a/include/trace/events/spmi.h b/include/trace/events/spmi.h
new file mode 100644
index 0000000..62f005e
--- /dev/null
+++ b/include/trace/events/spmi.h
@@ -0,0 +1,135 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM spmi
+
+#if !defined(_TRACE_SPMI_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SPMI_H
+
+#include <linux/spmi.h>
+#include <linux/tracepoint.h>
+
+/*
+ * drivers/spmi/spmi.c
+ */
+
+TRACE_EVENT(spmi_write_begin,
+	TP_PROTO(u8 opcode, u8 sid, u16 addr, u8 len, const u8 *buf),
+	TP_ARGS(opcode, sid, addr, len, buf),
+
+	TP_STRUCT__entry(
+		__field		( u8,         opcode    )
+		__field		( u8,         sid       )
+		__field		( u16,        addr      )
+		__field		( u8,         len       )
+		__dynamic_array	( u8,   buf,  len + 1   )
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+		__entry->sid    = sid;
+		__entry->addr   = addr;
+		__entry->len    = len + 1;
+		memcpy(__get_dynamic_array(buf), buf, len + 1);
+	),
+
+	TP_printk("opc=%d sid=%02d addr=0x%04x len=%d buf=0x[%*phD]",
+		  (int)__entry->opcode, (int)__entry->sid,
+		  (int)__entry->addr, (int)__entry->len,
+		  (int)__entry->len, __get_dynamic_array(buf))
+);
+
+TRACE_EVENT(spmi_write_end,
+	TP_PROTO(u8 opcode, u8 sid, u16 addr, int ret),
+	TP_ARGS(opcode, sid, addr, ret),
+
+	TP_STRUCT__entry(
+		__field		( u8,         opcode    )
+		__field		( u8,         sid       )
+		__field		( u16,        addr      )
+		__field		( int,        ret       )
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+		__entry->sid    = sid;
+		__entry->addr   = addr;
+		__entry->ret    = ret;
+	),
+
+	TP_printk("opc=%d sid=%02d addr=0x%04x ret=%d",
+		  (int)__entry->opcode, (int)__entry->sid,
+		  (int)__entry->addr, __entry->ret)
+);
+
+TRACE_EVENT(spmi_read_begin,
+	TP_PROTO(u8 opcode, u8 sid, u16 addr),
+	TP_ARGS(opcode, sid, addr),
+
+	TP_STRUCT__entry(
+		__field		( u8,         opcode    )
+		__field		( u8,         sid       )
+		__field		( u16,        addr      )
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+		__entry->sid    = sid;
+		__entry->addr   = addr;
+	),
+
+	TP_printk("opc=%d sid=%02d addr=0x%04x",
+		  (int)__entry->opcode, (int)__entry->sid,
+		  (int)__entry->addr)
+);
+
+TRACE_EVENT(spmi_read_end,
+	TP_PROTO(u8 opcode, u8 sid, u16 addr, int ret, u8 len, const u8 *buf),
+	TP_ARGS(opcode, sid, addr, ret, len, buf),
+
+	TP_STRUCT__entry(
+		__field		( u8,         opcode    )
+		__field		( u8,         sid       )
+		__field		( u16,        addr      )
+		__field		( int,        ret       )
+		__field		( u8,         len       )
+		__dynamic_array	( u8,   buf,  len + 1   )
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+		__entry->sid    = sid;
+		__entry->addr   = addr;
+		__entry->ret    = ret;
+		__entry->len    = len + 1;
+		memcpy(__get_dynamic_array(buf), buf, len + 1);
+	),
+
+	TP_printk("opc=%d sid=%02d addr=0x%04x ret=%d len=%02d buf=0x[%*phD]",
+		  (int)__entry->opcode, (int)__entry->sid,
+		  (int)__entry->addr, __entry->ret, (int)__entry->len,
+		  (int)__entry->len, __get_dynamic_array(buf))
+);
+
+TRACE_EVENT(spmi_cmd,
+	TP_PROTO(u8 opcode, u8 sid, int ret),
+	TP_ARGS(opcode, sid, ret),
+
+	TP_STRUCT__entry(
+		__field		( u8,         opcode    )
+		__field		( u8,         sid       )
+		__field		( int,        ret       )
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+		__entry->sid    = sid;
+		__entry->ret    = ret;
+	),
+
+	TP_printk("opc=%d sid=%02d ret=%d", (int)__entry->opcode,
+		  (int)__entry->sid, ret)
+);
+
+#endif /* _TRACE_SPMI_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH RESEND V3] spmi: add command tracepoints for SPMI
From: Ankit Gupta @ 2015-06-22 22:38 UTC (permalink / raw)
  To: gavidov, sdharia, linux-arm-kernel, linux-kernel, gregkh,
	sachin.kamat, sboyd, rostedt, mingo
  Cc: linux-arm-msm, mlocke, agross, Ankit Gupta

Add tracepoints to retrieve information about read, write
and non-data commands. For performance measurement support
tracepoints are added at the beginning and at the end of
transfers. Following is a list showing the new tracepoint
events. The "cmd" parameter here represents the opcode, SID,
and full 16-bit address.

spmi_write_begin: cmd and data buffer.
spmi_write_end  : cmd and return value.
spmi_read_begin : cmd.
spmi_read_end   : cmd, return value and data buffer.
spmi_cmd        : cmd.

The reason that cmd appears at both the beginning and at
the end event is that SPMI drivers can request commands
concurrently. cmd helps in matching the corresponding
events.

SPMI tracepoints can be enabled like:

echo 1 >/sys/kernel/debug/tracing/events/spmi/enable

and will dump messages that can be viewed in
/sys/kernel/debug/tracing/trace that look like:

... spmi_read_begin: opc=56 sid=00 addr=0x0000
... spmi_read_end: opc=56 sid=00 addr=0x0000 ret=0 len=02 buf=0x[01-40]
... spmi_write_begin: opc=48 sid=00 addr=0x0000 len=3 buf=0x[ff-ff-ff]

Suggested-by: Sagar Dharia <sdharia@codeaurora.org>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Gilad Avidov <gavidov@codeaurora.org>
Signed-off-by: Ankit Gupta <ankgupta@codeaurora.org>

---
Changes since v2:
- use full names in events: wr->write, rd->read, beg->begin.
- Edited the commit text to reflect full names of event.
---
Changes since V1:
- Change from ':' to "=" in printk in spmi.h.
- Added extra line between declaration and Code in spmi.c.
- Added use and example of spmi dump message in commit text.
---
 drivers/spmi/spmi.c         |  22 +++++++-
 include/trace/events/spmi.h | 135 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 154 insertions(+), 3 deletions(-)
 create mode 100644 include/trace/events/spmi.h

diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
index 1d92f51..36fe010 100644
--- a/drivers/spmi/spmi.c
+++ b/drivers/spmi/spmi.c
@@ -21,6 +21,8 @@
 #include <linux/pm_runtime.h>
 
 #include <dt-bindings/spmi/spmi.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/spmi.h>
 
 static DEFINE_IDA(ctrl_ida);
 
@@ -95,28 +97,42 @@ EXPORT_SYMBOL_GPL(spmi_device_remove);
 static inline int
 spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid)
 {
+	int ret;
+
 	if (!ctrl || !ctrl->cmd || ctrl->dev.type != &spmi_ctrl_type)
 		return -EINVAL;
 
-	return ctrl->cmd(ctrl, opcode, sid);
+	ret = ctrl->cmd(ctrl, opcode, sid);
+	trace_spmi_cmd(opcode, sid, ret);
+	return ret;
 }
 
 static inline int spmi_read_cmd(struct spmi_controller *ctrl, u8 opcode,
 				u8 sid, u16 addr, u8 *buf, size_t len)
 {
+	int ret;
+
 	if (!ctrl || !ctrl->read_cmd || ctrl->dev.type != &spmi_ctrl_type)
 		return -EINVAL;
 
-	return ctrl->read_cmd(ctrl, opcode, sid, addr, buf, len);
+	trace_spmi_read_begin(opcode, sid, addr);
+	ret = ctrl->read_cmd(ctrl, opcode, sid, addr, buf, len);
+	trace_spmi_read_end(opcode, sid, addr, ret, len, buf);
+	return ret;
 }
 
 static inline int spmi_write_cmd(struct spmi_controller *ctrl, u8 opcode,
 				 u8 sid, u16 addr, const u8 *buf, size_t len)
 {
+	int ret;
+
 	if (!ctrl || !ctrl->write_cmd || ctrl->dev.type != &spmi_ctrl_type)
 		return -EINVAL;
 
-	return ctrl->write_cmd(ctrl, opcode, sid, addr, buf, len);
+	trace_spmi_write_begin(opcode, sid, addr, len, buf);
+	ret = ctrl->write_cmd(ctrl, opcode, sid, addr, buf, len);
+	trace_spmi_write_end(opcode, sid, addr, ret);
+	return ret;
 }
 
 /**
diff --git a/include/trace/events/spmi.h b/include/trace/events/spmi.h
new file mode 100644
index 0000000..62f005e
--- /dev/null
+++ b/include/trace/events/spmi.h
@@ -0,0 +1,135 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM spmi
+
+#if !defined(_TRACE_SPMI_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SPMI_H
+
+#include <linux/spmi.h>
+#include <linux/tracepoint.h>
+
+/*
+ * drivers/spmi/spmi.c
+ */
+
+TRACE_EVENT(spmi_write_begin,
+	TP_PROTO(u8 opcode, u8 sid, u16 addr, u8 len, const u8 *buf),
+	TP_ARGS(opcode, sid, addr, len, buf),
+
+	TP_STRUCT__entry(
+		__field		( u8,         opcode    )
+		__field		( u8,         sid       )
+		__field		( u16,        addr      )
+		__field		( u8,         len       )
+		__dynamic_array	( u8,   buf,  len + 1   )
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+		__entry->sid    = sid;
+		__entry->addr   = addr;
+		__entry->len    = len + 1;
+		memcpy(__get_dynamic_array(buf), buf, len + 1);
+	),
+
+	TP_printk("opc=%d sid=%02d addr=0x%04x len=%d buf=0x[%*phD]",
+		  (int)__entry->opcode, (int)__entry->sid,
+		  (int)__entry->addr, (int)__entry->len,
+		  (int)__entry->len, __get_dynamic_array(buf))
+);
+
+TRACE_EVENT(spmi_write_end,
+	TP_PROTO(u8 opcode, u8 sid, u16 addr, int ret),
+	TP_ARGS(opcode, sid, addr, ret),
+
+	TP_STRUCT__entry(
+		__field		( u8,         opcode    )
+		__field		( u8,         sid       )
+		__field		( u16,        addr      )
+		__field		( int,        ret       )
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+		__entry->sid    = sid;
+		__entry->addr   = addr;
+		__entry->ret    = ret;
+	),
+
+	TP_printk("opc=%d sid=%02d addr=0x%04x ret=%d",
+		  (int)__entry->opcode, (int)__entry->sid,
+		  (int)__entry->addr, __entry->ret)
+);
+
+TRACE_EVENT(spmi_read_begin,
+	TP_PROTO(u8 opcode, u8 sid, u16 addr),
+	TP_ARGS(opcode, sid, addr),
+
+	TP_STRUCT__entry(
+		__field		( u8,         opcode    )
+		__field		( u8,         sid       )
+		__field		( u16,        addr      )
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+		__entry->sid    = sid;
+		__entry->addr   = addr;
+	),
+
+	TP_printk("opc=%d sid=%02d addr=0x%04x",
+		  (int)__entry->opcode, (int)__entry->sid,
+		  (int)__entry->addr)
+);
+
+TRACE_EVENT(spmi_read_end,
+	TP_PROTO(u8 opcode, u8 sid, u16 addr, int ret, u8 len, const u8 *buf),
+	TP_ARGS(opcode, sid, addr, ret, len, buf),
+
+	TP_STRUCT__entry(
+		__field		( u8,         opcode    )
+		__field		( u8,         sid       )
+		__field		( u16,        addr      )
+		__field		( int,        ret       )
+		__field		( u8,         len       )
+		__dynamic_array	( u8,   buf,  len + 1   )
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+		__entry->sid    = sid;
+		__entry->addr   = addr;
+		__entry->ret    = ret;
+		__entry->len    = len + 1;
+		memcpy(__get_dynamic_array(buf), buf, len + 1);
+	),
+
+	TP_printk("opc=%d sid=%02d addr=0x%04x ret=%d len=%02d buf=0x[%*phD]",
+		  (int)__entry->opcode, (int)__entry->sid,
+		  (int)__entry->addr, __entry->ret, (int)__entry->len,
+		  (int)__entry->len, __get_dynamic_array(buf))
+);
+
+TRACE_EVENT(spmi_cmd,
+	TP_PROTO(u8 opcode, u8 sid, int ret),
+	TP_ARGS(opcode, sid, ret),
+
+	TP_STRUCT__entry(
+		__field		( u8,         opcode    )
+		__field		( u8,         sid       )
+		__field		( int,        ret       )
+	),
+
+	TP_fast_assign(
+		__entry->opcode = opcode;
+		__entry->sid    = sid;
+		__entry->ret    = ret;
+	),
+
+	TP_printk("opc=%d sid=%02d ret=%d", (int)__entry->opcode,
+		  (int)__entry->sid, ret)
+);
+
+#endif /* _TRACE_SPMI_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
-- 
1.8.5.2

^ permalink raw reply related

* [PATCH 23/27] perf stat: Remove perf_evsel__read_cb function
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* Re: [PATCH v4 04/19] for-each-ref: add '--points-at' option
From: Eric Sunshine @ 2015-06-22 22:38 UTC (permalink / raw)
  To: Karthik Nayak; +Cc: Git List, Christian Couder, Matthieu Moy
In-Reply-To: <1434919705-4884-4-git-send-email-karthik.188@gmail.com>

On Sun, Jun 21, 2015 at 4:48 PM, Karthik Nayak <karthik.188@gmail.com> wrote:
> Add the '--points-at' option provided by 'ref-filter'. The
> option lets the user to pick only refs which point to a particular
> commit.
>
> Add documentation and tests for the same.
>
> Based-on-patch-by: Jeff King <peff@peff.net>
> Mentored-by: Christian Couder <christian.couder@gmail.com>
> Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
> ---
> diff --git a/t/t6301-for-each-ref-filter.sh b/t/t6301-for-each-ref-filter.sh
> index b1fa8d4..67de3a7 100755
> --- a/t/t6301-for-each-ref-filter.sh
> +++ b/t/t6301-for-each-ref-filter.sh
> @@ -16,4 +16,24 @@ test_expect_success 'setup some history and refs' '
>         git update-ref refs/odd/spot master
>  '
>
> +test_expect_success 'filtering with --points-at' '
> +       cat >expect <<-\EOF &&
> +       refs/heads/master
> +       refs/odd/spot
> +       refs/tags/three
> +       EOF
> +       git for-each-ref --format="%(refname)" --points-at=master >actual &&
> +       test_cmp expect actual
> +'
> +
> +test_expect_success 'check signed tags with --points-at' '
> +       cat >expect <<-\EOF &&
> +       refs/heads/side
> +       refs/tags/four
> +       refs/tags/signed-tag four
> +       EOF
> +       git for-each-ref  --format="%(refname) %(*subject)" --points-at=side >actual &&

s/for-each-ref\s+/for-each-ref /

> +       test_cmp expect actual
> +'
> +
>  test_done
> --
> 2.4.3.439.gfea0c2a.dirty

^ permalink raw reply

* [PATCH 21/27] perf stat: Move zero_per_pkg into counter process code
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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

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 74ac92baa2bd..b7c184bd559c 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -285,6 +285,9 @@ static int process_counter(struct perf_evsel *counter)
 
 	aggr->val = aggr->ena = aggr->run = 0;
 
+	if (counter->per_pkg)
+		zero_per_pkg(counter);
+
 	ret = process_counter_maps(counter);
 	if (ret)
 		return ret;
@@ -328,9 +331,6 @@ static int read_counter(struct perf_evsel *counter)
 	if (counter->system_wide)
 		nthreads = 1;
 
-	if (counter->per_pkg)
-		zero_per_pkg(counter);
-
 	for (thread = 0; thread < nthreads; thread++) {
 		for (cpu = 0; cpu < ncpus; cpu++) {
 			struct perf_counts_values *count;
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 2/2] x86/mm/pat, drivers/media/ivtv: replace WARN() with pr_warn()
From: Luis R. Rodriguez @ 2015-06-22 22:31 UTC (permalink / raw)
  To: bp, mchehab, dledford
  Cc: mingo, fengguang.wu, linux-media, linux-rdma, linux-kernel,
	Luis R. Rodriguez
In-Reply-To: <1435012318-381-1-git-send-email-mcgrof@do-not-panic.com>

From: "Luis R. Rodriguez" <mcgrof@suse.com>

On built-in kernels this will always splat. Fix that.

Reported-by: Fengguang Wu <fengguang.wu@intel.com> [0-day test robot]
Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
---
 drivers/media/pci/ivtv/ivtvfb.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/media/pci/ivtv/ivtvfb.c b/drivers/media/pci/ivtv/ivtvfb.c
index 4cb365d..6f0c364 100644
--- a/drivers/media/pci/ivtv/ivtvfb.c
+++ b/drivers/media/pci/ivtv/ivtvfb.c
@@ -38,6 +38,8 @@
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/fb.h>
@@ -1266,8 +1268,8 @@ static int __init ivtvfb_init(void)
 	int err;
 
 #ifdef CONFIG_X86_64
-	if (WARN(pat_enabled(),
-		 "ivtvfb needs PAT disabled, boot with nopat kernel parameter\n")) {
+	if (pat_enabled()) {
+		pr_warn("ivtvfb needs PAT disabled, boot with nopat kernel parameter\n");
 		return -ENODEV;
 	}
 #endif
-- 
2.3.2.209.gd67f9d5.dirty

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in

^ permalink raw reply related

* [PATCH 18/27] perf stat: Introduce perf_evsel__read function
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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 cd6ce7066f85..2e0a4e064f44 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -955,6 +955,20 @@ int perf_evsel__read_cb(struct perf_evsel *evsel, int cpu, int thread,
 	return cb(evsel, cpu, thread, &count);
 }
 
+int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
+		     struct perf_counts_values *count)
+{
+	memset(count, 0, sizeof(*count));
+
+	if (FD(evsel, cpu, thread) < 0)
+		return -EINVAL;
+
+	if (readn(FD(evsel, cpu, thread), count, sizeof(*count)) < 0)
+		return -errno;
+
+	return 0;
+}
+
 int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
 			      int cpu, int thread, bool scale)
 {
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 020f7e13634a..a79944a21e8f 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -236,6 +236,9 @@ typedef int (perf_evsel__read_cb_t)(struct perf_evsel *evsel,
 int perf_evsel__read_cb(struct perf_evsel *evsel, int cpu, int thread,
 			perf_evsel__read_cb_t cb);
 
+int perf_evsel__read(struct perf_evsel *evsel, int cpu, int thread,
+		     struct perf_counts_values *count);
+
 int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
 			      int cpu, int thread, bool scale);
 
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 17/27] perf stat: Introduce perf_evsel__alloc_stats function
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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

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

diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 818cb022fcb6..f2a0d1521e26 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -189,17 +189,25 @@ void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
 	evsel->prev_raw_counts = NULL;
 }
 
+int perf_evsel__alloc_stats(struct perf_evsel *evsel, bool alloc_raw)
+{
+	int ncpus = perf_evsel__nr_cpus(evsel);
+	int nthreads = thread_map__nr(evsel->threads);
+
+	if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
+	    perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
+	    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
+		return -ENOMEM;
+
+	return 0;
+}
+
 int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
 {
 	struct perf_evsel *evsel;
-	int nthreads = thread_map__nr(evlist->threads);
 
 	evlist__for_each(evlist, evsel) {
-		int ncpus = perf_evsel__nr_cpus(evsel);
-
-		if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
-		    perf_evsel__alloc_counts(evsel, ncpus, nthreads) < 0 ||
-		    (alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel, ncpus, nthreads) < 0))
+		if (perf_evsel__alloc_stats(evsel, alloc_raw))
 			goto out_free;
 	}
 
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 5f62db2472c7..9f05c571befe 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -103,6 +103,8 @@ int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
 				      int ncpus, int nthreads);
 void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel);
 
+int perf_evsel__alloc_stats(struct perf_evsel *evsel, bool alloc_raw);
+
 int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw);
 void perf_evlist__free_stats(struct perf_evlist *evlist);
 void perf_evlist__reset_stats(struct perf_evlist *evlist);
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 15/27] perf stat: Move perf_evsel__(alloc|free)_prev_raw_counts into stat object
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

Moving perf_evsel__(alloc|free)_prev_raw_counts into stat 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/stat.c    | 18 ++++++++++++++++++
 tools/perf/util/stat.h    |  4 ++++
 3 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 8a7fd0c60ab1..0ccba5c6b61d 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__new(ncpus, nthreads);
-	if (counts)
-		evsel->prev_raw_counts = counts;
-
-	return counts ? 0 : -ENOMEM;
-}
-
-static void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
-{
-	perf_counts__delete(evsel->prev_raw_counts);
-	evsel->prev_raw_counts = NULL;
-}
-
 static void perf_evlist__free_stats(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index b8c329f41f13..6221c3898397 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -168,3 +168,21 @@ void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
 {
 	zfree(&evsel->priv);
 }
+
+int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
+				      int ncpus, int nthreads)
+{
+	struct perf_counts *counts;
+
+	counts = perf_counts__new(ncpus, nthreads);
+	if (counts)
+		evsel->prev_raw_counts = counts;
+
+	return counts ? 0 : -ENOMEM;
+}
+
+void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel)
+{
+	perf_counts__delete(evsel->prev_raw_counts);
+	evsel->prev_raw_counts = NULL;
+}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index c441cb312565..454b26875aef 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -96,4 +96,8 @@ void perf_evsel__free_counts(struct perf_evsel *evsel);
 void perf_evsel__reset_stat_priv(struct perf_evsel *evsel);
 int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel);
 void perf_evsel__free_stat_priv(struct perf_evsel *evsel);
+
+int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel,
+				      int ncpus, int nthreads);
+void perf_evsel__free_prev_raw_counts(struct perf_evsel *evsel);
 #endif
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 14/27] perf stat: Move perf_evsel__(alloc|free|reset)_stat_priv into stat object
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

Moving perf_evsel__(alloc|free|reset)_stat_priv into stat object,
so it could be used outside stat command 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/stat.c    | 25 +++++++++++++++++++++++++
 tools/perf/util/stat.h    |  4 ++++
 3 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 188cd98a4ab3..8a7fd0c60ab1 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/stat.c b/tools/perf/util/stat.c
index 197a2db5f2c4..b8c329f41f13 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -143,3 +143,28 @@ void perf_evsel__free_counts(struct perf_evsel *evsel)
 	perf_counts__delete(evsel->counts);
 	evsel->counts = NULL;
 }
+
+void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
+{
+	int i;
+	struct perf_stat *ps = evsel->priv;
+
+	for (i = 0; i < 3; i++)
+		init_stats(&ps->res_stats[i]);
+
+	perf_stat_evsel_id_init(evsel);
+}
+
+int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
+{
+	evsel->priv = zalloc(sizeof(struct perf_stat));
+	if (evsel->priv == NULL)
+		return -ENOMEM;
+	perf_evsel__reset_stat_priv(evsel);
+	return 0;
+}
+
+void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
+{
+	zfree(&evsel->priv);
+}
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 295d1e29d3d6..c441cb312565 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -92,4 +92,8 @@ void perf_counts__delete(struct perf_counts *counts);
 void perf_evsel__reset_counts(struct perf_evsel *evsel);
 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus, int nthreads);
 void perf_evsel__free_counts(struct perf_evsel *evsel);
+
+void perf_evsel__reset_stat_priv(struct perf_evsel *evsel);
+int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel);
+void perf_evsel__free_stat_priv(struct perf_evsel *evsel);
 #endif
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 13/27] perf stat: Introduce perf_evlist__reset_stats
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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

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

diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 983bcbbe8e0a..188cd98a4ab3 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -216,7 +216,7 @@ out_free:
 	return -1;
 }
 
-static void perf_stat__reset_stats(struct perf_evlist *evlist)
+static void perf_evlist__reset_stats(struct perf_evlist *evlist)
 {
 	struct perf_evsel *evsel;
 
@@ -224,7 +224,11 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
 		perf_evsel__reset_stat_priv(evsel);
 		perf_evsel__reset_counts(evsel);
 	}
+}
 
+static void perf_stat__reset_stats(void)
+{
+	perf_evlist__reset_stats(evsel_list);
 	perf_stat__reset_shadow_stats();
 }
 
@@ -1473,7 +1477,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
 		status = run_perf_stat(argc, argv);
 		if (forever && status != -1) {
 			print_stat(argc, argv);
-			perf_stat__reset_stats(evsel_list);
+			perf_stat__reset_stats();
 		}
 	}
 
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 11/27] perf stat: Make stats work over the thread dimension
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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                    | 12 +++++------
 tools/perf/util/evsel.h                    |  2 +-
 tools/perf/util/stat.c                     |  8 ++++----
 tools/perf/util/stat.h                     |  8 ++++----
 7 files changed, 38 insertions(+), 34 deletions(-)

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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 07/27] perf tools: Make perf_evsel__(nr_)cpus generic
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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 fcf99bdeb19e..3e1636cae76b 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 9e16a5c4eb01..4dbf32d94dfb 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 06/27] perf tools: Propagate thread maps through the evlist
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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

It'll be handy to access evsel's threads directly
in following patches. The reason is there's no link
from evsel to evlist which hold threads map now and
evlist is not always available.

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 214affaf1cf6..6cfdee68e763 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1117,7 +1117,9 @@ static int perf_evlist__propagate_maps(struct perf_evlist *evlist,
 		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 31b0afb68825..1b2f480a3e82 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -886,6 +886,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 bb0579e8a10a..9e16a5c4eb01 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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 05/27] perf tools: Propagate cpu maps through the evlist
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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 | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index a8d18a3d2164..214affaf1cf6 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -1101,6 +1101,29 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
 	return perf_evlist__mmap_ex(evlist, pages, overwrite, 0, false);
 }
 
+static int perf_evlist__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,
@@ -1117,7 +1140,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
 	if (evlist->cpus == NULL)
 		goto out_delete_threads;
 
-	return 0;
+	return perf_evlist__propagate_maps(evlist, target);
 
 out_delete_threads:
 	thread_map__put(evlist->threads);
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 04/27] perf tools: Add reference counting for thread_map object
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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               | 31 ++++++++++++++++++++++++++----
 tools/perf/util/thread_map.h               |  7 +++++--
 11 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 6b3250f54240..39c784a100a9 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 7f48efa7e295..145050e2e544 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, 500);
 
-	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 9a7a116e09b8..b8d552b13950 100644
--- a/tools/perf/tests/openat-syscall-all-cpus.c
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -111,6 +111,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 59498f7b3e9b..a8d18a3d2164 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);
@@ -1120,7 +1120,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 5b2f2495af26..7b41aacdbc69 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -9,6 +9,7 @@
 #include "strlist.h"
 #include <string.h>
 #include <api/fs/fs.h>
+#include "asm/bug.h"
 #include "thread_map.h"
 #include "util.h"
 #include "debug.h"
@@ -96,6 +97,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid)
 			comm_init(threads, i);
 		}
 		threads->nr = items;
+		atomic_set(&threads->refcnt, 1);
 	}
 
 	for (i=0; i<items; i++)
@@ -113,6 +115,7 @@ struct thread_map *thread_map__new_by_tid(pid_t tid)
 		thread_map__set_pid(threads, 0, tid);
 		threads->nr = 1;
 		comm_init(threads, 0);
+		atomic_set(&threads->refcnt, 1);
 	}
 
 	return threads;
@@ -134,6 +137,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
 		goto out_free_threads;
 
 	threads->nr = 0;
+	atomic_set(&threads->refcnt, 1);
 
 	while (!readdir_r(proc, &dirent, &next) && next) {
 		char *end;
@@ -264,6 +268,8 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
 
 out:
 	strlist__delete(slist);
+	if (threads)
+		atomic_set(&threads->refcnt, 1);
 	return threads;
 
 out_free_namelist:
@@ -284,6 +290,7 @@ struct thread_map *thread_map__new_dummy(void)
 		thread_map__set_pid(threads, 0, -1);
 		threads->nr = 1;
 		comm_init(threads, 0);
+		atomic_set(&threads->refcnt, 1);
 	}
 	return threads;
 }
@@ -327,6 +334,8 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
 		comm_init(threads, ntasks - 1);
 	}
 out:
+	if (threads)
+		atomic_set(&threads->refcnt, 1);
 	return threads;
 
 out_free_threads:
@@ -346,16 +355,30 @@ 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)
 {
-	int i;
-
 	if (threads) {
+		int i;
+
+		WARN_ONCE(atomic_read(&threads->refcnt) != 0,
+			  "thread map refcnt disbalanced\n");
 		for (i = 0; i < threads->nr; i++)
 			free(thread_map__comm(threads, i));
+		free(threads);
 	}
+}
 
-	free(threads);
+struct thread_map *thread_map__get(struct thread_map *map)
+{
+	if (map)
+		atomic_inc(&map->refcnt);
+	return map;
+}
+
+void thread_map__put(struct thread_map *map)
+{
+	if (map && atomic_dec_and_test(&map->refcnt))
+		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 0f67843475e6..70c575b14318 100644
--- a/tools/perf/util/thread_map.h
+++ b/tools/perf/util/thread_map.h
@@ -3,6 +3,7 @@
 
 #include <sys/types.h>
 #include <stdio.h>
+#include <linux/atomic.h>
 
 struct thread_map_data {
 	pid_t    pid;
@@ -10,6 +11,7 @@ struct thread_map_data {
 };
 
 struct thread_map {
+	atomic_t refcnt;
 	int nr;
 	struct thread_map_data map[];
 };
@@ -20,11 +22,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

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 02/27] perf tools: Add comm string into struct thread_map
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

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

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

Link: http://lkml.kernel.org/n/tip-pf6bgmbujukce0sgliuhj2f4@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/python-ext-sources |  1 +
 tools/perf/util/thread_map.c       | 67 ++++++++++++++++++++++++++++++++++++--
 tools/perf/util/thread_map.h       | 12 +++++++
 3 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources
index 5925fec90562..e23ded40c79e 100644
--- a/tools/perf/util/python-ext-sources
+++ b/tools/perf/util/python-ext-sources
@@ -20,3 +20,4 @@ util/stat.c
 util/strlist.c
 util/trace-event.c
 ../../lib/rbtree.c
+util/string.c
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index 7a4be3754d05..5b2f2495af26 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -8,8 +8,10 @@
 #include <unistd.h>
 #include "strlist.h"
 #include <string.h>
+#include <api/fs/fs.h>
 #include "thread_map.h"
 #include "util.h"
+#include "debug.h"
 
 /* Skip "." and ".." directories */
 static int filter(const struct dirent *dir)
@@ -29,6 +31,51 @@ static struct thread_map *thread_map__realloc(struct thread_map *map, int nr)
 
 #define thread_map__alloc(__nr) thread_map__realloc(NULL, __nr)
 
+static int get_comm(char **comm, pid_t pid)
+{
+	char *path;
+	size_t size;
+	int err;
+
+	if (asprintf(&path, "%s/%d/comm", procfs__mountpoint(), pid) == -1)
+		return -ENOMEM;
+
+	err = filename__read_str(path, comm, &size);
+	if (!err) {
+		/*
+		 * We're reading 16 bytes, while filename__read_str
+		 * allocates data per BUFSIZ bytes, so we can safely
+		 * mark the end of the string.
+		 */
+		(*comm)[size] = 0;
+		rtrim(*comm);
+	}
+
+	free(path);
+	return err;
+}
+
+static void comm_init(struct thread_map *map, int i)
+{
+	pid_t pid = thread_map__pid(map, i);
+	char *comm = NULL;
+
+	/* dummy pid comm initialization */
+	if (pid == -1) {
+		thread_map__set_comm(map, i, strdup("dummy"));
+		return;
+	}
+
+	/*
+	 * The comm name is like extra bonus ;-),
+	 * so just warn if we fail for any reason.
+	 */
+	if (get_comm(&comm, pid))
+		pr_warning("Couldn't resolve comm name for pid %d\n", pid);
+
+	thread_map__set_comm(map, i, comm);
+}
+
 struct thread_map *thread_map__new_by_pid(pid_t pid)
 {
 	struct thread_map *threads;
@@ -44,8 +91,10 @@ struct thread_map *thread_map__new_by_pid(pid_t pid)
 
 	threads = thread_map__alloc(items);
 	if (threads != NULL) {
-		for (i = 0; i < items; i++)
+		for (i = 0; i < items; i++) {
 			thread_map__set_pid(threads, i, atoi(namelist[i]->d_name));
+			comm_init(threads, i);
+		}
 		threads->nr = items;
 	}
 
@@ -63,6 +112,7 @@ struct thread_map *thread_map__new_by_tid(pid_t tid)
 	if (threads != NULL) {
 		thread_map__set_pid(threads, 0, tid);
 		threads->nr = 1;
+		comm_init(threads, 0);
 	}
 
 	return threads;
@@ -126,6 +176,7 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
 		for (i = 0; i < items; i++) {
 			thread_map__set_pid(threads, threads->nr + i,
 					    atoi(namelist[i]->d_name));
+			comm_init(threads, threads->nr + i);
 		}
 
 		for (i = 0; i < items; i++)
@@ -202,8 +253,9 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
 
 		threads = nt;
 
-		for (i = 0; i < items; i++) {
-			thread_map__set_pid(threads, j++, atoi(namelist[i]->d_name));
+		for (i = 0; i < items; i++, j++) {
+			thread_map__set_pid(threads, j, atoi(namelist[i]->d_name));
+			comm_init(threads, j);
 			zfree(&namelist[i]);
 		}
 		threads->nr = total_tasks;
@@ -231,6 +283,7 @@ struct thread_map *thread_map__new_dummy(void)
 	if (threads != NULL) {
 		thread_map__set_pid(threads, 0, -1);
 		threads->nr = 1;
+		comm_init(threads, 0);
 	}
 	return threads;
 }
@@ -271,6 +324,7 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
 		threads = nt;
 		thread_map__set_pid(threads, ntasks - 1, tid);
 		threads->nr = ntasks;
+		comm_init(threads, ntasks - 1);
 	}
 out:
 	return threads;
@@ -294,6 +348,13 @@ struct thread_map *thread_map__new_str(const char *pid, const char *tid,
 
 void thread_map__delete(struct thread_map *threads)
 {
+	int i;
+
+	if (threads) {
+		for (i = 0; i < threads->nr; i++)
+			free(thread_map__comm(threads, i));
+	}
+
 	free(threads);
 }
 
diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h
index b9f40679f589..0f67843475e6 100644
--- a/tools/perf/util/thread_map.h
+++ b/tools/perf/util/thread_map.h
@@ -6,6 +6,7 @@
 
 struct thread_map_data {
 	pid_t    pid;
+	char	*comm;
 };
 
 struct thread_map {
@@ -41,4 +42,15 @@ thread_map__set_pid(struct thread_map *map, int thread, pid_t pid)
 {
 	map->map[thread].pid = pid;
 }
+
+static inline char *thread_map__comm(struct thread_map *map, int thread)
+{
+	return map->map[thread].comm;
+}
+
+static inline void
+thread_map__set_comm(struct thread_map *map, int thread, char *comm)
+{
+	map->map[thread].comm = comm;
+}
 #endif	/* __PERF_THREAD_MAP_H */
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCH 01/27] perf tools: Change thread_map::map into struct
From: Jiri Olsa @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Arnaldo Carvalho de Melo
  Cc: lkml, Adrian Hunter, Andi Kleen, David Ahern, Ingo Molnar,
	Namhyung Kim, Peter Zijlstra, Stephane Eranian
In-Reply-To: <1435012588-9007-1-git-send-email-jolsa@kernel.org>

We need to store command names with the pid. Changing
map to be struct holding pid. Process name is coming
in shortly.

Link: http://lkml.kernel.org/n/tip-z4zuyvcxa6glzqm8qubk6vg7@git.kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-trace.c                  |  4 ++--
 tools/perf/tests/openat-syscall-tp-fields.c |  2 +-
 tools/perf/util/auxtrace.c                  |  4 ++--
 tools/perf/util/event.c                     |  6 +++---
 tools/perf/util/evlist.c                    |  4 ++--
 tools/perf/util/evsel.c                     |  2 +-
 tools/perf/util/thread_map.c                | 26 ++++++++++++++------------
 tools/perf/util/thread_map.h                | 16 +++++++++++++++-
 8 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index de5d277d1ad7..2bf2ca771ca5 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2325,7 +2325,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
 	 */
 	if (trace->filter_pids.nr > 0)
 		err = perf_evlist__set_filter_pids(evlist, trace->filter_pids.nr, trace->filter_pids.entries);
-	else if (evlist->threads->map[0] == -1)
+	else if (thread_map__pid(evlist->threads, 0) == -1)
 		err = perf_evlist__set_filter_pid(evlist, getpid());
 
 	if (err < 0) {
@@ -2343,7 +2343,7 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
 	if (forks)
 		perf_evlist__start_workload(evlist);
 
-	trace->multiple_threads = evlist->threads->map[0] == -1 ||
+	trace->multiple_threads = thread_map__pid(evlist->threads, 0) == -1 ||
 				  evlist->threads->nr > 1 ||
 				  perf_evlist__first(evlist)->attr.inherit;
 again:
diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c
index 6245221479d7..01a19626c846 100644
--- a/tools/perf/tests/openat-syscall-tp-fields.c
+++ b/tools/perf/tests/openat-syscall-tp-fields.c
@@ -45,7 +45,7 @@ int test__syscall_openat_tp_fields(void)
 
 	perf_evsel__config(evsel, &opts);
 
-	evlist->threads->map[0] = getpid();
+	thread_map__set_pid(evlist->threads, 0, getpid());
 
 	err = perf_evlist__open(evlist);
 	if (err < 0) {
diff --git a/tools/perf/util/auxtrace.c b/tools/perf/util/auxtrace.c
index df66966cfde7..3dab006b4a03 100644
--- a/tools/perf/util/auxtrace.c
+++ b/tools/perf/util/auxtrace.c
@@ -119,12 +119,12 @@ void auxtrace_mmap_params__set_idx(struct auxtrace_mmap_params *mp,
 	if (per_cpu) {
 		mp->cpu = evlist->cpus->map[idx];
 		if (evlist->threads)
-			mp->tid = evlist->threads->map[0];
+			mp->tid = thread_map__pid(evlist->threads, 0);
 		else
 			mp->tid = -1;
 	} else {
 		mp->cpu = -1;
-		mp->tid = evlist->threads->map[idx];
+		mp->tid = thread_map__pid(evlist->threads, idx);
 	}
 }
 
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index d7d986d8f23e..67a977e5d0ab 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -504,7 +504,7 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
 	for (thread = 0; thread < threads->nr; ++thread) {
 		if (__event__synthesize_thread(comm_event, mmap_event,
 					       fork_event,
-					       threads->map[thread], 0,
+					       thread_map__pid(threads, thread), 0,
 					       process, tool, machine,
 					       mmap_data, proc_map_timeout)) {
 			err = -1;
@@ -515,12 +515,12 @@ int perf_event__synthesize_thread_map(struct perf_tool *tool,
 		 * comm.pid is set to thread group id by
 		 * perf_event__synthesize_comm
 		 */
-		if ((int) comm_event->comm.pid != threads->map[thread]) {
+		if ((int) comm_event->comm.pid != thread_map__pid(threads, thread)) {
 			bool need_leader = true;
 
 			/* is thread group leader in thread_map? */
 			for (j = 0; j < threads->nr; ++j) {
-				if ((int) comm_event->comm.pid == threads->map[j]) {
+				if ((int) comm_event->comm.pid == thread_map__pid(threads, j)) {
 					need_leader = false;
 					break;
 				}
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 8366511b45f8..d29df901be3e 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -548,7 +548,7 @@ static void perf_evlist__set_sid_idx(struct perf_evlist *evlist,
 	else
 		sid->cpu = -1;
 	if (!evsel->system_wide && evlist->threads && thread >= 0)
-		sid->tid = evlist->threads->map[thread];
+		sid->tid = thread_map__pid(evlist->threads, thread);
 	else
 		sid->tid = -1;
 }
@@ -1475,7 +1475,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *tar
 				__func__, __LINE__);
 			goto out_close_pipes;
 		}
-		evlist->threads->map[0] = evlist->workload.pid;
+		thread_map__set_pid(evlist->threads, 0, evlist->workload.pid);
 	}
 
 	close(child_ready_pipe[1]);
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 33449decf7bd..1b56047af96b 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1167,7 +1167,7 @@ retry_sample_id:
 			int group_fd;
 
 			if (!evsel->cgrp && !evsel->system_wide)
-				pid = threads->map[thread];
+				pid = thread_map__pid(threads, thread);
 
 			group_fd = get_group_fd(evsel, cpu, thread);
 retry_open:
diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c
index f4822bd03709..7a4be3754d05 100644
--- a/tools/perf/util/thread_map.c
+++ b/tools/perf/util/thread_map.c
@@ -22,7 +22,7 @@ static int filter(const struct dirent *dir)
 
 static struct thread_map *thread_map__realloc(struct thread_map *map, int nr)
 {
-	size_t size = sizeof(*map) + sizeof(pid_t) * nr;
+	size_t size = sizeof(*map) + sizeof(struct thread_map_data) * nr;
 
 	return realloc(map, size);
 }
@@ -45,7 +45,7 @@ struct thread_map *thread_map__new_by_pid(pid_t pid)
 	threads = thread_map__alloc(items);
 	if (threads != NULL) {
 		for (i = 0; i < items; i++)
-			threads->map[i] = atoi(namelist[i]->d_name);
+			thread_map__set_pid(threads, i, atoi(namelist[i]->d_name));
 		threads->nr = items;
 	}
 
@@ -61,8 +61,8 @@ struct thread_map *thread_map__new_by_tid(pid_t tid)
 	struct thread_map *threads = thread_map__alloc(1);
 
 	if (threads != NULL) {
-		threads->map[0] = tid;
-		threads->nr	= 1;
+		thread_map__set_pid(threads, 0, tid);
+		threads->nr = 1;
 	}
 
 	return threads;
@@ -123,8 +123,10 @@ struct thread_map *thread_map__new_by_uid(uid_t uid)
 			threads = tmp;
 		}
 
-		for (i = 0; i < items; i++)
-			threads->map[threads->nr + i] = atoi(namelist[i]->d_name);
+		for (i = 0; i < items; i++) {
+			thread_map__set_pid(threads, threads->nr + i,
+					    atoi(namelist[i]->d_name));
+		}
 
 		for (i = 0; i < items; i++)
 			zfree(&namelist[i]);
@@ -201,7 +203,7 @@ static struct thread_map *thread_map__new_by_pid_str(const char *pid_str)
 		threads = nt;
 
 		for (i = 0; i < items; i++) {
-			threads->map[j++] = atoi(namelist[i]->d_name);
+			thread_map__set_pid(threads, j++, atoi(namelist[i]->d_name));
 			zfree(&namelist[i]);
 		}
 		threads->nr = total_tasks;
@@ -227,8 +229,8 @@ struct thread_map *thread_map__new_dummy(void)
 	struct thread_map *threads = thread_map__alloc(1);
 
 	if (threads != NULL) {
-		threads->map[0]	= -1;
-		threads->nr	= 1;
+		thread_map__set_pid(threads, 0, -1);
+		threads->nr = 1;
 	}
 	return threads;
 }
@@ -267,8 +269,8 @@ static struct thread_map *thread_map__new_by_tid_str(const char *tid_str)
 			goto out_free_threads;
 
 		threads = nt;
-		threads->map[ntasks - 1] = tid;
-		threads->nr		 = ntasks;
+		thread_map__set_pid(threads, ntasks - 1, tid);
+		threads->nr = ntasks;
 	}
 out:
 	return threads;
@@ -301,7 +303,7 @@ size_t thread_map__fprintf(struct thread_map *threads, FILE *fp)
 	size_t printed = fprintf(fp, "%d thread%s: ",
 				 threads->nr, threads->nr > 1 ? "s" : "");
 	for (i = 0; i < threads->nr; ++i)
-		printed += fprintf(fp, "%s%d", i ? ", " : "", threads->map[i]);
+		printed += fprintf(fp, "%s%d", i ? ", " : "", thread_map__pid(threads, i));
 
 	return printed + fprintf(fp, "\n");
 }
diff --git a/tools/perf/util/thread_map.h b/tools/perf/util/thread_map.h
index 95313f43cc0f..b9f40679f589 100644
--- a/tools/perf/util/thread_map.h
+++ b/tools/perf/util/thread_map.h
@@ -4,9 +4,13 @@
 #include <sys/types.h>
 #include <stdio.h>
 
+struct thread_map_data {
+	pid_t    pid;
+};
+
 struct thread_map {
 	int nr;
-	pid_t map[];
+	struct thread_map_data map[];
 };
 
 struct thread_map *thread_map__new_dummy(void);
@@ -27,4 +31,14 @@ static inline int thread_map__nr(struct thread_map *threads)
 	return threads ? threads->nr : 1;
 }
 
+static inline pid_t thread_map__pid(struct thread_map *map, int thread)
+{
+	return map->map[thread].pid;
+}
+
+static inline void
+thread_map__set_pid(struct thread_map *map, int thread, pid_t pid)
+{
+	map->map[thread].pid = pid;
+}
 #endif	/* __PERF_THREAD_MAP_H */
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply related

* [PATCHv4 00/27] perf stat: Introduce --per-thread option
From: Jiri Olsa @ 2015-06-22 22:36 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-thread -p 30190,30242
  ^C
   Performance counter stats for process id '30190,30242':

               cat-30190                     0      cycles
               yes-30242         3,842,525,421      cycles
               cat-30190                     0      instructions
               yes-30242        10,370,817,010      instructions

         1.143155657 seconds time elapsed


Also works under interval mode:

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


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

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

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

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


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

 tools/perf/Documentation/perf-stat.txt      |   4 +
 tools/perf/builtin-stat.c                   | 404 ++++++++++++++--------------
 tools/perf/builtin-trace.c                  |   4 +-
 tools/perf/tests/Build                      |   1 +
 tools/perf/tests/builtin-test.c             |   4 +
 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-tp-fields.c |   2 +-
 tools/perf/tests/openat-syscall.c           |   6 +-
 tools/perf/tests/switch-tracking.c          |   4 +-
 tools/perf/tests/tests.h                    |   1 +
 tools/perf/tests/thread-map.c               |  28 ++
 tools/perf/util/auxtrace.c                  |   4 +-
 tools/perf/util/cpumap.c                    |  26 +-
 tools/perf/util/cpumap.h                    |   6 +-
 tools/perf/util/event.c                     |   6 +-
 tools/perf/util/evlist.c                    |  39 ++-
 tools/perf/util/evlist.h                    |   1 -
 tools/perf/util/evsel.c                     |  28 +-
 tools/perf/util/evsel.h                     |  40 ++-
 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.c                      | 132 ++++++++-
 tools/perf/util/stat.h                      |  47 +++-
 tools/perf/util/svghelper.c                 |   2 +-
 tools/perf/util/thread_map.c                | 118 ++++++--
 tools/perf/util/thread_map.h                |  35 ++-
 33 files changed, 661 insertions(+), 319 deletions(-)
 create mode 100644 tools/perf/tests/thread-map.c
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* Re: [PATCH v4 03/19] ref-filter: implement '--points-at' option
From: Eric Sunshine @ 2015-06-22 22:36 UTC (permalink / raw)
  To: Karthik Nayak; +Cc: Git List, Christian Couder, Matthieu Moy
In-Reply-To: <1434919705-4884-3-git-send-email-karthik.188@gmail.com>

On Sun, Jun 21, 2015 at 4:48 PM, Karthik Nayak <karthik.188@gmail.com> wrote:
> In 'tag -l' we have '--points-at' option which lets users
> list only tags which point to a particular commit. Implement
> this option in 'ref-filter.{c,h}' so that other commands can
> benefit from this.
>
> This is duplicated from tag.c, we will eventually remove that
> when we port tag.c to use ref-filter APIs.
>
> Based-on-patch-by: Jeff King <peff@peff.net>
> Mentored-by: Christian Couder <christian.couder@gmail.com>
> Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
> Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
> ---
> diff --git a/builtin/tag.c b/builtin/tag.c
> index e36c43e..280981f 100644
> --- a/builtin/tag.c
> +++ b/builtin/tag.c
> @@ -56,6 +56,10 @@ static int match_pattern(const char **patterns, const char *ref)
>         return 0;
>  }
>
> +/*
> + * This is currently duplicated in ref-filter.c, and will eventually be
> + * removed as we port tag.c to use the ref-filter APIs.
> + */
>  static const unsigned char *match_points_at(const char *refname,
>                                             const unsigned char *sha1)
>  {
> diff --git a/ref-filter.c b/ref-filter.c
> index 43502a4..591e281 100644
> --- a/ref-filter.c
> +++ b/ref-filter.c
> @@ -842,6 +842,29 @@ static int match_name_as_path(const char **pattern, const char *refname)
>         return 0;
>  }
>
> +/*
> + * Given a ref (sha1, refname) see if it points to a one of the sha1s

s/a one/one/

> + * in a sha1_array.
> + */
> +static int match_points_at(struct sha1_array *points_at, const unsigned char *sha1,
> +                          const char *refname)
> +{
> +       struct object *obj;
> +
> +       if (!points_at || !points_at->nr)
> +               return 1;
> +
> +       if (sha1_array_lookup(points_at, sha1) >= 0)
> +               return 1;
> +
> +       obj = parse_object_or_die(sha1, refname);
> +       if (obj->type == OBJ_TAG &&
> +           sha1_array_lookup(points_at, ((struct tag *)obj)->tagged->sha1) >= 0)
> +               return 1;
> +
> +       return 0;
> +}

^ permalink raw reply


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.