linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support
@ 2013-02-04 12:32 Jiri Olsa
  2013-02-04 12:32 ` [PATCH 01/11] perf ui/hist: Add support to display whole group data for raw columns Jiri Olsa
                   ` (11 more replies)
  0 siblings, 12 replies; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

hi,
adding support to read sample values through the PERF_SAMPLE_READ
sample type. It's now possible to specify 'S' modifier for an event
and get its sample value by PERF_SAMPLE_READ.

For group the 'S' modifier will enable sampling only for the leader
and read all the group member by PERF_SAMPLE_READ smple type with
PERF_FORMAT_GROUP read format.

This was first introduced in here:
https://lkml.org/lkml/2012/10/20/75

Example:

  $ perf record -e '{cycles,cache-misses}:S' ls
  ...
  $ perf report --group --show-total-period --stdio
  ...
  # Samples: 36  of event 'anon group { cycles, cache-misses }'
  # Event count (approx.): 12585593
  #
  #         Overhead                    Period  Command      Shared Object                      Symbol
  # ................  ........................  .......  .................  ..........................
  #
      19.92%   1.20%       2505936          31       ls  [kernel.kallsyms]  [k] mark_held_locks
      13.74%   0.47%       1729327          12       ls  [kernel.kallsyms]  [k] sched_clock_local
      13.64%  23.72%       1716147         612       ls  ld-2.14.90.so      [.] check_match.10805
      13.12%  23.22%       1650778         599       ls  libc-2.14.90.so    [.] _nl_intern_locale_data
      11.24%  29.19%       1414554         753       ls  [kernel.kallsyms]  [k] sched_clock_cpu
       8.50%   0.35%       1070150           9       ls  [kernel.kallsyms]  [k] check_chain_key
  ...


The patchset is based on following fix:
http://lkml.org/lkml/2013/2/4/122

and is available also at:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/linux.git
perf/group6

TODO: add column names as suggested by Ingo in the original discussion.

thanks,
jirka


Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
Jiri Olsa (11):
      perf ui/hist: Add support to display whole group data for raw columns
      perf: Add PERF_EVENT_IOC_ID ioctl to return event ID
      perf: Do not get values from disabled counters in group format read
      perf tools: Use PERF_EVENT_IOC_ID perf ioctl to read event id
      perf tools: Add support for parsing PERF_SAMPLE_READ sample type
      perf tools: Fix event ID retrieval for group format read case
      perf tools: Add perf_evlist__id2sid function to get event ID related data
      perf tools: Add PERF_SAMPLE_READ sample related processing
      perf tools: Add 'S' event/group modifier to read sample value
      perf tests: Add attr record group sampling test
      perf tests: Add parse events tests for leader sampling

 include/uapi/linux/perf_event.h                  |   1 +
 kernel/events/core.c                             |  12 ++++++++-
 tools/perf/Documentation/perf-list.txt           |   1 +
 tools/perf/tests/attr/test-record-group-sampling |  36 ++++++++++++++++++++++++++
 tools/perf/tests/parse-events.c                  | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/ui/hist.c                             |  53 +++++++++++++++++++-------------------
 tools/perf/util/event.h                          |  18 +++++++++++++
 tools/perf/util/evlist.c                         |  73 +++++++++++++++++++++++++++++++++++++++++++++++-----
 tools/perf/util/evlist.h                         |   4 +++
 tools/perf/util/evsel.c                          |  59 ++++++++++++++++++++++++++++++++++++++++--
 tools/perf/util/evsel.h                          |   4 +++
 tools/perf/util/parse-events.c                   |   8 +++++-
 tools/perf/util/parse-events.l                   |   2 +-
 tools/perf/util/session.c                        | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 14 files changed, 457 insertions(+), 39 deletions(-)

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

* [PATCH 01/11] perf ui/hist: Add support to display whole group data for raw columns
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
@ 2013-02-04 12:32 ` Jiri Olsa
  2013-02-06  4:41   ` Namhyung Kim
  2013-02-06 22:10   ` [tip:perf/core] perf hists browser: " tip-bot for Jiri Olsa
  2013-02-04 12:32 ` [PATCH 02/11] perf: Add PERF_EVENT_IOC_ID ioctl to return event ID Jiri Olsa
                   ` (10 subsequent siblings)
  11 siblings, 2 replies; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

Currently we don't display group members' values for raw
columns like 'Samples' and 'Period' when in group report
mode.

Uniting '__hpp__percent_fmt' and '__hpp__raw_fmt' function under
new function __hpp__fmt. It's basically '__hpp__percent_fmt' code
with new 'fmt_percent' bool parameter added saying whether raw
number or percentage should be printed.

This way raw columns print out all the group members when
in group report mode, like:

  $ perf record -e '{cycles,cache-misses}' ls
  ...
  $ perf report --group --show-total-period --stdio
  ...
  #         Overhead                    Period  Command      Shared Object                             Symbol
  # ................  ........................  .......  .................  .................................
  #
      23.63%  11.24%       3331335         317       ls  [kernel.kallsyms]  [k] __lock_acquire
      12.72%   0.00%       1793100           0       ls  [kernel.kallsyms]  [k] native_sched_clock
       9.72%   0.00%       1369920           0       ls  libc-2.14.90.so    [.] _nl_find_locale
       0.03%   0.07%          4476           2       ls  [kernel.kallsyms]  [k] intel_pmu_enable_all
       0.00%  11.73%             0         331       ls  ld-2.14.90.so      [.] _dl_cache_libcmp
       0.00%  11.06%             0         312       ls  [kernel.kallsyms]  [k] vma_interval_tree_insert

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/ui/hist.c | 53 ++++++++++++++++++++++++++--------------------------
 1 file changed, 26 insertions(+), 27 deletions(-)

diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index a47ce98..d671e63 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -9,18 +9,24 @@
 
 typedef int (*hpp_snprint_fn)(char *buf, size_t size, const char *fmt, ...);
 
-static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he,
-			      u64 (*get_field)(struct hist_entry *),
-			      const char *fmt, hpp_snprint_fn print_fn)
+static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
+		      u64 (*get_field)(struct hist_entry *),
+		      const char *fmt, hpp_snprint_fn print_fn,
+		      bool fmt_percent)
 {
 	int ret;
-	double percent = 0.0;
 	struct hists *hists = he->hists;
 
-	if (hists->stats.total_period)
-		percent = 100.0 * get_field(he) / hists->stats.total_period;
+	if (fmt_percent) {
+		double percent = 0.0;
+
+		if (hists->stats.total_period)
+			percent = 100.0 * get_field(he) /
+				  hists->stats.total_period;
 
-	ret = print_fn(hpp->buf, hpp->size, fmt, percent);
+		ret = print_fn(hpp->buf, hpp->size, fmt, percent);
+	} else
+		ret = print_fn(hpp->buf, hpp->size, fmt, get_field(he));
 
 	if (symbol_conf.event_group) {
 		int prev_idx, idx_delta;
@@ -49,11 +55,15 @@ static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he,
 				 * have no sample
 				 */
 				ret += print_fn(hpp->buf + ret, hpp->size - ret,
-						fmt, 0.0);
+						fmt, 0);
 			}
 
-			ret += print_fn(hpp->buf + ret, hpp->size - ret,
-					fmt, 100.0 * period / total);
+			if (fmt_percent)
+				ret += print_fn(hpp->buf + ret, hpp->size - ret,
+						fmt, 100.0 * period / total);
+			else
+				ret += print_fn(hpp->buf + ret, hpp->size - ret,
+						fmt, period);
 
 			prev_idx = perf_evsel__group_idx(evsel);
 		}
@@ -65,23 +75,12 @@ static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he,
 			 * zero-fill group members at last which have no sample
 			 */
 			ret += print_fn(hpp->buf + ret, hpp->size - ret,
-					fmt, 0.0);
+					fmt, 0);
 		}
 	}
 	return ret;
 }
 
-static int __hpp__raw_fmt(struct perf_hpp *hpp, struct hist_entry *he,
-			  u64 (*get_field)(struct hist_entry *),
-			  const char *fmt, hpp_snprint_fn print_fn)
-{
-	int ret;
-
-	ret = print_fn(hpp->buf, hpp->size, fmt, get_field(he));
-	return ret;
-}
-
-
 #define __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) 		\
 static int hpp__header_##_type(struct perf_hpp *hpp)			\
 {									\
@@ -116,16 +115,16 @@ static u64 he_get_##_field(struct hist_entry *he)				\
 										\
 static int hpp__color_##_type(struct perf_hpp *hpp, struct hist_entry *he) 	\
 {										\
-	return __hpp__percent_fmt(hpp, he, he_get_##_field, " %6.2f%%",		\
-				  (hpp_snprint_fn)percent_color_snprintf); 	\
+	return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%",			\
+			  (hpp_snprint_fn)percent_color_snprintf, true);	\
 }
 
 #define __HPP_ENTRY_PERCENT_FN(_type, _field)					\
 static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) 	\
 {										\
 	const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%";		\
-	return __hpp__percent_fmt(hpp, he, he_get_##_field, fmt,		\
-				  scnprintf);					\
+	return __hpp__fmt(hpp, he, he_get_##_field, fmt,			\
+			  scnprintf, true);					\
 }
 
 #define __HPP_ENTRY_RAW_FN(_type, _field)					\
@@ -137,7 +136,7 @@ static u64 he_get_raw_##_field(struct hist_entry *he)				\
 static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) 	\
 {										\
 	const char *fmt = symbol_conf.field_sep ? " %"PRIu64 : " %11"PRIu64;	\
-	return __hpp__raw_fmt(hpp, he, he_get_raw_##_field, fmt, scnprintf);	\
+	return __hpp__fmt(hpp, he, he_get_raw_##_field, fmt, scnprintf, false);	\
 }
 
 #define HPP_PERCENT_FNS(_type, _str, _field, _min_width, _unit_width)	\
-- 
1.7.11.7


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

* [PATCH 02/11] perf: Add PERF_EVENT_IOC_ID ioctl to return event ID
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
  2013-02-04 12:32 ` [PATCH 01/11] perf ui/hist: Add support to display whole group data for raw columns Jiri Olsa
@ 2013-02-04 12:32 ` Jiri Olsa
  2013-05-02 13:38   ` Peter Zijlstra
  2013-02-04 12:32 ` [PATCH 03/11] perf: Do not get values from disabled counters in group format read Jiri Olsa
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

From: "jolsa@redhat.com" <jolsa@redhat.com>

The only way to get the event ID is by reading the event fd,
followed by parsing the ID value out of the returned data.

While this is ok for current read format used by perf tool,
it is not ok when we use PERF_FORMAT_GROUP format.

With this format the data are returned for the whole group
and there's no way to find out what ID belongs to our fd
(if we are not group leader event).

Adding a simple ioctl that returns event primary ID for given fd.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 include/uapi/linux/perf_event.h | 1 +
 kernel/events/core.c            | 9 +++++++++
 2 files changed, 10 insertions(+)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 9fa9c62..b4ea8ed 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -316,6 +316,7 @@ struct perf_event_attr {
 #define PERF_EVENT_IOC_PERIOD		_IOW('$', 4, __u64)
 #define PERF_EVENT_IOC_SET_OUTPUT	_IO ('$', 5)
 #define PERF_EVENT_IOC_SET_FILTER	_IOW('$', 6, char *)
+#define PERF_EVENT_IOC_ID		_IOR('$', 7, u64 *)
 
 enum perf_event_ioc_flags {
 	PERF_IOC_FLAG_GROUP		= 1U << 0,
diff --git a/kernel/events/core.c b/kernel/events/core.c
index 301079d..4081261 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3277,6 +3277,15 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 	case PERF_EVENT_IOC_PERIOD:
 		return perf_event_period(event, (u64 __user *)arg);
 
+	case PERF_EVENT_IOC_ID:
+	{
+		u64 id = primary_event_id(event);
+
+		if (copy_to_user((void __user *)arg, &id, sizeof(id)))
+			return -EFAULT;
+		return 0;
+	}
+
 	case PERF_EVENT_IOC_SET_OUTPUT:
 	{
 		int ret;
-- 
1.7.11.7


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

* [PATCH 03/11] perf: Do not get values from disabled counters in group format read
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
  2013-02-04 12:32 ` [PATCH 01/11] perf ui/hist: Add support to display whole group data for raw columns Jiri Olsa
  2013-02-04 12:32 ` [PATCH 02/11] perf: Add PERF_EVENT_IOC_ID ioctl to return event ID Jiri Olsa
@ 2013-02-04 12:32 ` Jiri Olsa
  2013-05-02 13:39   ` Peter Zijlstra
  2013-02-04 12:32 ` [PATCH 04/11] perf tools: Use PERF_EVENT_IOC_ID perf ioctl to read event id Jiri Olsa
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

From: "jolsa@redhat.com" <jolsa@redhat.com>

It's possible some of the counters in the group could be
disabled when sampling member of the event group is reading
the rest via PERF_SAMPLE_READ sample type processing. Disabled
counters could then produce wrong numbers.

Fixing that by reading only enabled counters for PERF_SAMPLE_READ
sample type processing.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 kernel/events/core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 4081261..e2ea1b9 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -4018,7 +4018,8 @@ static void perf_output_read_group(struct perf_output_handle *handle,
 	list_for_each_entry(sub, &leader->sibling_list, group_entry) {
 		n = 0;
 
-		if (sub != event)
+		if ((sub != event) &&
+		    (sub->state == PERF_EVENT_STATE_ACTIVE))
 			sub->pmu->read(sub);
 
 		values[n++] = perf_event_count(sub);
-- 
1.7.11.7


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

* [PATCH 04/11] perf tools: Use PERF_EVENT_IOC_ID perf ioctl to read event id
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
                   ` (2 preceding siblings ...)
  2013-02-04 12:32 ` [PATCH 03/11] perf: Do not get values from disabled counters in group format read Jiri Olsa
@ 2013-02-04 12:32 ` Jiri Olsa
  2013-02-04 12:32 ` [PATCH 05/11] perf tools: Add support for parsing PERF_SAMPLE_READ sample type Jiri Olsa
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

Changing the way we retrieve the event ID. Instead of parsing out
the ID out of the read data, using the PERF_EVENT_IOC_ID ioctl.

Keeping the old way in place to support kernels without
PERF_EVENT_IOC_ID ioctl support.

This will be useful for retrieving the event ID for events
with PERF_FORMAT_GROUP read format set, where it's impossible
to get correct event id out of the read call data.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/evlist.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index eddd5eb..51e21f9 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -298,6 +298,17 @@ static int perf_evlist__id_add_fd(struct perf_evlist *evlist,
 {
 	u64 read_data[4] = { 0, };
 	int id_idx = 1; /* The first entry is the counter value */
+	u64 id;
+	int ret;
+
+	ret = ioctl(fd, PERF_EVENT_IOC_ID, &id);
+	if (!ret)
+		goto add;
+
+	if (errno != ENOTTY)
+		return -1;
+
+	/* Legacy way to get event id.. All hail to old kernels! */
 
 	if (!(evsel->attr.read_format & PERF_FORMAT_ID) ||
 	    read(fd, &read_data, sizeof(read_data)) == -1)
@@ -308,7 +319,10 @@ static int perf_evlist__id_add_fd(struct perf_evlist *evlist,
 	if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
 		++id_idx;
 
-	perf_evlist__id_add(evlist, evsel, cpu, thread, read_data[id_idx]);
+	id = read_data[id_idx];
+
+ add:
+	perf_evlist__id_add(evlist, evsel, cpu, thread, id);
 	return 0;
 }
 
-- 
1.7.11.7


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

* [PATCH 05/11] perf tools: Add support for parsing PERF_SAMPLE_READ sample type
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
                   ` (3 preceding siblings ...)
  2013-02-04 12:32 ` [PATCH 04/11] perf tools: Use PERF_EVENT_IOC_ID perf ioctl to read event id Jiri Olsa
@ 2013-02-04 12:32 ` Jiri Olsa
  2013-02-04 12:33 ` [PATCH 06/11] perf tools: Fix event ID retrieval for group format read case Jiri Olsa
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:32 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

Adding support to parse out the PERF_SAMPLE_READ sample bits.
The code contains both single and group format specification.

This code parse out and prepare PERF_SAMPLE_READ data into the
perf_sample struct. It will be used for group leader sampling
feature comming in shortly.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/event.h   | 18 ++++++++++++++++++
 tools/perf/util/evlist.c  | 27 +++++++++++++++++++++++++++
 tools/perf/util/evlist.h  |  2 ++
 tools/perf/util/evsel.c   | 30 ++++++++++++++++++++++++++++--
 tools/perf/util/session.c | 38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 113 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 0d573ff..108da52 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -80,6 +80,23 @@ struct stack_dump {
 	char *data;
 };
 
+struct sample_read_value {
+	u64 value;
+	u64 id;
+};
+
+struct sample_read {
+	u64 time_enabled;
+	u64 time_running;
+	union {
+		struct {
+			u64 nr;
+			struct sample_read_value *values;
+		} group;
+		struct sample_read_value one;
+	};
+};
+
 struct perf_sample {
 	u64 ip;
 	u32 pid, tid;
@@ -95,6 +112,7 @@ struct perf_sample {
 	struct branch_stack *branch_stack;
 	struct regs_dump  user_regs;
 	struct stack_dump user_stack;
+	struct sample_read read;
 };
 
 struct build_id_event {
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 51e21f9..5ba5509 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -674,6 +674,33 @@ u64 perf_evlist__sample_type(struct perf_evlist *evlist)
 	return first->attr.sample_type;
 }
 
+bool perf_evlist__valid_read_format(struct perf_evlist *evlist)
+{
+	struct perf_evsel *first = perf_evlist__first(evlist), *pos = first;
+	u64 read_format = first->attr.read_format;
+	u64 sample_type = first->attr.sample_type;
+
+	list_for_each_entry_continue(pos, &evlist->entries, node) {
+		if (read_format != pos->attr.read_format)
+			return false;
+	}
+
+	/* PERF_SAMPLE_READ imples PERF_FORMAT_ID. */
+	if ((sample_type & PERF_SAMPLE_READ) &&
+	    !(read_format & PERF_FORMAT_ID)) {
+		pr_err("Wrong format type for sample read type.\n");
+		return false;
+	}
+
+	return true;
+}
+
+u64 perf_evlist__read_format(struct perf_evlist *evlist)
+{
+	struct perf_evsel *first = perf_evlist__first(evlist);
+	return first->attr.read_format;
+}
+
 u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist)
 {
 	struct perf_evsel *first = perf_evlist__first(evlist);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 73579a2..0b7297c 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -111,6 +111,7 @@ int perf_evlist__apply_filters(struct perf_evlist *evlist);
 void __perf_evlist__set_leader(struct list_head *list);
 void perf_evlist__set_leader(struct perf_evlist *evlist);
 
+u64 perf_evlist__read_format(struct perf_evlist *evlist);
 u64 perf_evlist__sample_type(struct perf_evlist *evlist);
 bool perf_evlist__sample_id_all(struct perf_evlist *evlist);
 u16 perf_evlist__id_hdr_size(struct perf_evlist *evlist);
@@ -120,6 +121,7 @@ int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *even
 
 bool perf_evlist__valid_sample_type(struct perf_evlist *evlist);
 bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist);
+bool perf_evlist__valid_read_format(struct perf_evlist *evlist);
 
 void perf_evlist__splice_list_tail(struct perf_evlist *evlist,
 				   struct list_head *list,
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index a547015..f841f5d 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -1084,8 +1084,34 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
 	}
 
 	if (type & PERF_SAMPLE_READ) {
-		fprintf(stderr, "PERF_SAMPLE_READ is unsupported for now\n");
-		return -1;
+		u64 read_format = evsel->attr.read_format;
+
+		if (read_format & PERF_FORMAT_GROUP)
+			data->read.group.nr = *array;
+		else
+			data->read.one.value = *array;
+
+		array++;
+
+		if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
+			data->read.time_enabled = *array;
+			array++;
+		}
+
+		if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
+			data->read.time_running = *array;
+			array++;
+		}
+
+		/* PERF_FORMAT_ID is forced for PERF_SAMPLE_READ */
+		if (read_format & PERF_FORMAT_GROUP) {
+			data->read.group.values = (struct sample_read_value *) array;
+			array = (void *) array + data->read.group.nr *
+				sizeof(struct sample_read_value);
+		} else {
+			data->read.one.id = *array;
+			array++;
+		}
 	}
 
 	if (type & PERF_SAMPLE_CALLCHAIN) {
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index bd85280b..0612ae5 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -73,6 +73,11 @@ static int perf_session__open(struct perf_session *self, bool force)
 		goto out_close;
 	}
 
+	if (!perf_evlist__valid_read_format(self->evlist)) {
+		pr_err("non matching read_format");
+		goto out_close;
+	}
+
 	self->size = input_stat.st_size;
 	return 0;
 
@@ -757,6 +762,36 @@ static void perf_session__print_tstamp(struct perf_session *session,
 		printf("%" PRIu64 " ", sample->time);
 }
 
+static void sample_read__printf(struct perf_sample *sample, u64 read_format)
+{
+	printf("... sample_read:\n");
+
+	if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
+		printf("...... time enabled %016" PRIx64 "\n",
+		       sample->read.time_enabled);
+
+	if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
+		printf("...... time running %016" PRIx64 "\n",
+		       sample->read.time_running);
+
+	if (read_format & PERF_FORMAT_GROUP) {
+		u64 i;
+
+		printf(".... group nr %" PRIu64 "\n", sample->read.group.nr);
+
+		for (i = 0; i < sample->read.group.nr; i++) {
+			struct sample_read_value *value;
+
+			value = &sample->read.group.values[i];
+			printf("..... id %016" PRIx64
+			       ", value %016" PRIx64 "\n",
+			       value->id, value->value);
+		}
+	} else
+		printf("..... id %016" PRIx64 ", value %016" PRIx64 "\n",
+			sample->read.one.id, sample->read.one.value);
+}
+
 static void dump_event(struct perf_session *session, union perf_event *event,
 		       u64 file_offset, struct perf_sample *sample)
 {
@@ -800,6 +835,9 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
 
 	if (sample_type & PERF_SAMPLE_STACK_USER)
 		stack_user__printf(&sample->user_stack);
+
+	if (sample_type & PERF_SAMPLE_READ)
+		sample_read__printf(sample, evsel->attr.read_format);
 }
 
 static struct machine *
-- 
1.7.11.7


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

* [PATCH 06/11] perf tools: Fix event ID retrieval for group format read case
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
                   ` (4 preceding siblings ...)
  2013-02-04 12:32 ` [PATCH 05/11] perf tools: Add support for parsing PERF_SAMPLE_READ sample type Jiri Olsa
@ 2013-02-04 12:33 ` Jiri Olsa
  2013-02-04 12:33 ` [PATCH 07/11] perf tools: Add perf_evlist__id2sid function to get event ID related data Jiri Olsa
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

From: "jolsa@redhat.com" <jolsa@redhat.com>

We need to fail the event ID retrieval in case both following
conditions are true:
  - we are on kernel with no PERF_EVENT_IOC_ID support
  - PERF_FORMAT_GROUP read format is set

The PERF_FORMAT_GROUP read format bit is the killer for
retrieving event ID out of the read syscall, because we
have no guarantee of the event placement within leader
kernel sibling list.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/evlist.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 5ba5509..8789adf 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -310,6 +310,15 @@ static int perf_evlist__id_add_fd(struct perf_evlist *evlist,
 
 	/* Legacy way to get event id.. All hail to old kernels! */
 
+	/*
+	 * This way does not work with group format read, so bail
+	 * out in that case.
+	 */
+	if (perf_evlist__read_format(evlist) & PERF_FORMAT_GROUP) {
+		pr_err("No kernel support for ':S' group modifier\n");
+		return -1;
+	}
+
 	if (!(evsel->attr.read_format & PERF_FORMAT_ID) ||
 	    read(fd, &read_data, sizeof(read_data)) == -1)
 		return -1;
-- 
1.7.11.7


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

* [PATCH 07/11] perf tools: Add perf_evlist__id2sid function to get event ID related data
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
                   ` (5 preceding siblings ...)
  2013-02-04 12:33 ` [PATCH 06/11] perf tools: Fix event ID retrieval for group format read case Jiri Olsa
@ 2013-02-04 12:33 ` Jiri Olsa
  2013-02-04 12:33 ` [PATCH 08/11] perf tools: Add PERF_SAMPLE_READ sample related processing Jiri Olsa
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

Adding perf_evlist__id2sid function to be able to get ID related
data. This will be helpful for PERF_FORMAT_GROUP samples where
we need to store ID related period value for each event.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/evlist.c | 21 ++++++++++++++++-----
 tools/perf/util/evlist.h |  2 ++
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 8789adf..b7565ad 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -335,22 +335,33 @@ static int perf_evlist__id_add_fd(struct perf_evlist *evlist,
 	return 0;
 }
 
-struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
+struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id)
 {
 	struct hlist_head *head;
 	struct hlist_node *pos;
 	struct perf_sample_id *sid;
 	int hash;
 
-	if (evlist->nr_entries == 1)
-		return perf_evlist__first(evlist);
-
 	hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
 	head = &evlist->heads[hash];
 
 	hlist_for_each_entry(sid, pos, head, node)
 		if (sid->id == id)
-			return sid->evsel;
+			return sid;
+
+	return NULL;
+}
+
+struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
+{
+	struct perf_sample_id *sid;
+
+	if (evlist->nr_entries == 1)
+		return perf_evlist__first(evlist);
+
+	sid = perf_evlist__id2sid(evlist, id);
+	if (sid)
+		return sid->evsel;
 
 	if (!perf_evlist__sample_id_all(evlist))
 		return perf_evlist__first(evlist);
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 0b7297c..565f114 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -73,6 +73,8 @@ void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd);
 
 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);
 
+struct perf_sample_id *perf_evlist__id2sid(struct perf_evlist *evlist, u64 id);
+
 union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
 
 int perf_evlist__open(struct perf_evlist *evlist);
-- 
1.7.11.7


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

* [PATCH 08/11] perf tools: Add PERF_SAMPLE_READ sample related processing
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
                   ` (6 preceding siblings ...)
  2013-02-04 12:33 ` [PATCH 07/11] perf tools: Add perf_evlist__id2sid function to get event ID related data Jiri Olsa
@ 2013-02-04 12:33 ` Jiri Olsa
  2013-02-04 12:33 ` [PATCH 09/11] perf tools: Add 'S' event/group modifier to read sample value Jiri Olsa
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

For sample with sample type PERF_SAMPLE_READ the period value is
stored in the 'struct sample_read'.

Moreover if the read format has PERF_FORMAT_GROUP, the 'struct
sample_read' contains period values for all events in the group
(for which the sample's event is a leader).

We deliver separated samples for all the values contained
within the 'struct sample_read'.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/util/evsel.h   |  3 ++
 tools/perf/util/session.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 74 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 8512f6a..a05d008 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -37,6 +37,9 @@ struct perf_sample_id {
 	struct hlist_node 	node;
 	u64		 	id;
 	struct perf_evsel	*evsel;
+
+	/* Holds total ID period value for PERF_SAMPLE_READ processing. */
+	u64			period;
 };
 
 /** struct perf_evsel - event selector
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 0612ae5..3b32acc 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -862,6 +862,75 @@ static struct machine *
 	return &session->machines.host;
 }
 
+static int deliver_sample_value(struct perf_session *session,
+				struct perf_tool *tool,
+				union perf_event *event,
+				struct perf_sample *sample,
+				struct sample_read_value *v,
+				struct machine *machine)
+{
+	struct perf_sample_id *sid;
+
+	sid = perf_evlist__id2sid(session->evlist, v->id);
+	if (sid) {
+		sample->id     = v->id;
+		sample->period = v->value - sid->period;
+		sid->period    = v->value;
+	}
+
+	if (!sid || sid->evsel == NULL) {
+		++session->stats.nr_unknown_id;
+		return 0;
+	}
+
+	return tool->sample(tool, event, sample, sid->evsel, machine);
+}
+
+static int deliver_sample_group(struct perf_session *session,
+				struct perf_tool *tool,
+				union  perf_event *event,
+				struct perf_sample *sample,
+				struct machine *machine)
+{
+	int ret = -EINVAL;
+	u64 i;
+
+	for (i = 0; i < sample->read.group.nr; i++) {
+		ret = deliver_sample_value(session, tool, event, sample,
+					   &sample->read.group.values[i],
+					   machine);
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
+
+static int
+perf_session__deliver_sample(struct perf_session *session,
+			     struct perf_tool *tool,
+			     union  perf_event *event,
+			     struct perf_sample *sample,
+			     struct perf_evsel *evsel,
+			     struct machine *machine)
+{
+	/* We know evsel != NULL. */
+	u64 sample_type = evsel->attr.sample_type;
+	u64 read_format = evsel->attr.read_format;
+
+	/* Standard sample delievery. */
+	if (!(sample_type & PERF_SAMPLE_READ))
+		return tool->sample(tool, event, sample, evsel, machine);
+
+	/* For PERF_SAMPLE_READ we have either single or group mode. */
+	if (read_format & PERF_FORMAT_GROUP)
+		return deliver_sample_group(session, tool, event, sample,
+					    machine);
+	else
+		return deliver_sample_value(session, tool, event, sample,
+					    &sample->read.one, machine);
+}
+
 static int perf_session_deliver_event(struct perf_session *session,
 				      union perf_event *event,
 				      struct perf_sample *sample,
@@ -904,7 +973,8 @@ static int perf_session_deliver_event(struct perf_session *session,
 			++session->stats.nr_unprocessable_samples;
 			return 0;
 		}
-		return tool->sample(tool, event, sample, evsel, machine);
+		return perf_session__deliver_sample(session, tool, event,
+						    sample, evsel, machine);
 	case PERF_RECORD_MMAP:
 		return tool->mmap(tool, event, sample, machine);
 	case PERF_RECORD_COMM:
-- 
1.7.11.7


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

* [PATCH 09/11] perf tools: Add 'S' event/group modifier to read sample value
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
                   ` (7 preceding siblings ...)
  2013-02-04 12:33 ` [PATCH 08/11] perf tools: Add PERF_SAMPLE_READ sample related processing Jiri Olsa
@ 2013-02-04 12:33 ` Jiri Olsa
  2013-02-04 12:33 ` [PATCH 10/11] perf tests: Add attr record group sampling test Jiri Olsa
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

Adding 'S' event/group modifier to specify that the event value/s
are read by PERF_SAMPLE_READ sample type processing, instead of the
period value offered by lower layers.

There's additional behaviour change for 'S' modifier being specified
on event group:

Currently all the events within a group makes samples. If user now
specifies 'S' within group modifier, only the leader will trigger
samples. The rest of events in the group will have sampling disabled.

And same as for single events, values of all events within the group
(including leader) are read by PERF_SAMPLE_READ sample type processing.

Following example will create event group with cycles and cache-misses
events, setting the cycles as group leader and the only event to actually
sample. Both cycles and cache-misses event period values are read by
PERF_SAMPLE_READ sample type processing with PERF_FORMAT_GROUP read format.

Example:

  $ perf record -e '{cycles,cache-misses}:S' ls
  ...
  $ perf report --group --show-total-period --stdio
  ...
  # Samples: 36  of event 'anon group { cycles, cache-misses }'
  # Event count (approx.): 12585593
  #
  #         Overhead                    Period  Command      Shared Object                      Symbol
  # ................  ........................  .......  .................  ..........................
  #
      19.92%   1.20%       2505936          31       ls  [kernel.kallsyms]  [k] mark_held_locks
      13.74%   0.47%       1729327          12       ls  [kernel.kallsyms]  [k] sched_clock_local
      13.64%  23.72%       1716147         612       ls  ld-2.14.90.so      [.] check_match.10805
      13.12%  23.22%       1650778         599       ls  libc-2.14.90.so    [.] _nl_intern_locale_data
      11.24%  29.19%       1414554         753       ls  [kernel.kallsyms]  [k] sched_clock_cpu
       8.50%   0.35%       1070150           9       ls  [kernel.kallsyms]  [k] check_chain_key
  ...

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/Documentation/perf-list.txt |  1 +
 tools/perf/util/evsel.c                | 29 +++++++++++++++++++++++++++++
 tools/perf/util/evsel.h                |  1 +
 tools/perf/util/parse-events.c         |  8 +++++++-
 tools/perf/util/parse-events.l         |  2 +-
 5 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index d1e39dc..7ddef65 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -29,6 +29,7 @@ counted. The following modifiers exist:
  G - guest counting (in KVM guests)
  H - host counting (not in KVM guests)
  p - precise level
+ S - read sample value (PERF_SAMPLE_READ)
 
 The 'p' modifier can be used for specifying how precise the instruction
 address should be. The 'p' modifier can be specified multiple times:
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index f841f5d..f00e307 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -490,6 +490,7 @@ int perf_evsel__group_desc(struct perf_evsel *evsel, char *buf, size_t size)
 void perf_evsel__config(struct perf_evsel *evsel,
 			struct perf_record_opts *opts)
 {
+	struct perf_evsel *leader = evsel->leader;
 	struct perf_event_attr *attr = &evsel->attr;
 	int track = !evsel->idx; /* only the first counter needs these */
 
@@ -499,6 +500,25 @@ void perf_evsel__config(struct perf_evsel *evsel,
 	perf_evsel__set_sample_bit(evsel, IP);
 	perf_evsel__set_sample_bit(evsel, TID);
 
+	if (evsel->sample_read) {
+		perf_evsel__set_sample_bit(evsel, READ);
+
+		/*
+		 * We need ID even in case of single event, because
+		 * PERF_SAMPLE_READ process ID specific data.
+		 */
+		perf_evsel__set_sample_id(evsel);
+
+		/*
+		 * Apply group format only if we belong to group
+		 * with more than one members.
+		 */
+		if (leader->nr_members > 1) {
+			attr->read_format |= PERF_FORMAT_GROUP;
+			attr->inherit = 0;
+		}
+	}
+
 	/*
 	 * We default some events to a 1 default interval. But keep
 	 * it a weak assumption overridable by the user.
@@ -514,6 +534,15 @@ void perf_evsel__config(struct perf_evsel *evsel,
 		}
 	}
 
+	/*
+	 * Disable sampling for all group members other
+	 * than leader in case leader 'leads' the sampling.
+	 */
+	if ((leader != evsel) && leader->sample_read) {
+		attr->sample_freq   = 0;
+		attr->sample_period = 0;
+	}
+
 	if (opts->no_samples)
 		attr->sample_freq = 0;
 
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index a05d008..6f74e71 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -78,6 +78,7 @@ struct perf_evsel {
 	/* parse modifier helper */
 	int			exclude_GH;
 	int			nr_members;
+	int			sample_read;
 	struct perf_evsel	*leader;
 	char			*group_name;
 };
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index c84f48c..9fff391 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -684,6 +684,7 @@ struct event_modifier {
 	int eG;
 	int precise;
 	int exclude_GH;
+	int sample_read;
 };
 
 static int get_event_modifier(struct event_modifier *mod, char *str,
@@ -695,6 +696,7 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
 	int eH = evsel ? evsel->attr.exclude_host : 0;
 	int eG = evsel ? evsel->attr.exclude_guest : 0;
 	int precise = evsel ? evsel->attr.precise_ip : 0;
+	int sample_read = 0;
 
 	int exclude = eu | ek | eh;
 	int exclude_GH = evsel ? evsel->exclude_GH : 0;
@@ -727,6 +729,8 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
 			/* use of precise requires exclude_guest */
 			if (!exclude_GH)
 				eG = 1;
+		} else if (*str == 'S') {
+			sample_read = 1;
 		} else
 			break;
 
@@ -753,6 +757,7 @@ static int get_event_modifier(struct event_modifier *mod, char *str,
 	mod->eG = eG;
 	mod->precise = precise;
 	mod->exclude_GH = exclude_GH;
+	mod->sample_read = sample_read;
 	return 0;
 }
 
@@ -765,7 +770,7 @@ static int check_modifier(char *str)
 	char *p = str;
 
 	/* The sizeof includes 0 byte as well. */
-	if (strlen(str) > (sizeof("ukhGHppp") - 1))
+	if (strlen(str) > (sizeof("ukhGHpppS") - 1))
 		return -1;
 
 	while (*p) {
@@ -803,6 +808,7 @@ int parse_events__modifier_event(struct list_head *list, char *str, bool add)
 		evsel->attr.exclude_host   = mod.eH;
 		evsel->attr.exclude_guest  = mod.eG;
 		evsel->exclude_GH          = mod.exclude_GH;
+		evsel->sample_read         = mod.sample_read;
 	}
 
 	return 0;
diff --git a/tools/perf/util/parse-events.l b/tools/perf/util/parse-events.l
index e9d1134..b36115f 100644
--- a/tools/perf/util/parse-events.l
+++ b/tools/perf/util/parse-events.l
@@ -82,7 +82,7 @@ num_hex		0x[a-fA-F0-9]+
 num_raw_hex	[a-fA-F0-9]+
 name		[a-zA-Z_*?][a-zA-Z0-9_*?]*
 name_minus	[a-zA-Z_*?][a-zA-Z0-9\-_*?]*
-modifier_event	[ukhpGH]+
+modifier_event	[ukhpGHS]+
 modifier_bp	[rwx]{1,3}
 
 %%
-- 
1.7.11.7


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

* [PATCH 10/11] perf tests: Add attr record group sampling test
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
                   ` (8 preceding siblings ...)
  2013-02-04 12:33 ` [PATCH 09/11] perf tools: Add 'S' event/group modifier to read sample value Jiri Olsa
@ 2013-02-04 12:33 ` Jiri Olsa
  2013-02-04 12:33 ` [PATCH 11/11] perf tests: Add parse events tests for leader sampling Jiri Olsa
  2013-02-06  4:59 ` [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Namhyung Kim
  11 siblings, 0 replies; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

Adding test to validate perf_event_attr data for command:
  'record -e '{cycles,cache-misses}:S'

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/tests/attr/test-record-group-sampling | 36 ++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 tools/perf/tests/attr/test-record-group-sampling

diff --git a/tools/perf/tests/attr/test-record-group-sampling b/tools/perf/tests/attr/test-record-group-sampling
new file mode 100644
index 0000000..658f5d6
--- /dev/null
+++ b/tools/perf/tests/attr/test-record-group-sampling
@@ -0,0 +1,36 @@
+[config]
+command = record
+args    = -e '{cycles,cache-misses}:S' kill >/dev/null 2>&1
+
+[event-1:base-record]
+fd=1
+group_fd=-1
+sample_type=343
+read_format=12
+inherit=0
+
+[event-2:base-record]
+fd=2
+group_fd=1
+
+# cache-misses
+type=0
+config=3
+
+# default | PERF_SAMPLE_READ
+sample_type=343
+
+# PERF_FORMAT_ID | PERF_FORMAT_GROUP
+read_format=12
+
+mmap=0
+comm=0
+enable_on_exec=0
+disabled=0
+
+# inherit is disabled for group sampling
+inherit=0
+
+# sampling disabled
+sample_freq=0
+sample_period=0
-- 
1.7.11.7


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

* [PATCH 11/11] perf tests: Add parse events tests for leader sampling
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
                   ` (9 preceding siblings ...)
  2013-02-04 12:33 ` [PATCH 10/11] perf tests: Add attr record group sampling test Jiri Olsa
@ 2013-02-04 12:33 ` Jiri Olsa
  2013-02-06  4:59 ` [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Namhyung Kim
  11 siblings, 0 replies; 17+ messages in thread
From: Jiri Olsa @ 2013-02-04 12:33 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Peter Zijlstra, Ingo Molnar,
	Paul Mackerras, Corey Ashford, Frederic Weisbecker, Namhyung Kim

Adding 2 more tests to the automated parse events suite
for following event config:

  '{cycles,cache-misses,branch-misses}:S'
  '{instructions,branch-misses}:Su'

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
---
 tools/perf/tests/parse-events.c | 115 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 115 insertions(+)

diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c
index c5636f3..9c4f45b 100644
--- a/tools/perf/tests/parse-events.c
+++ b/tools/perf/tests/parse-events.c
@@ -528,6 +528,7 @@ static int test__group1(struct perf_evlist *evlist)
 	TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
 	TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	/* cycles:upp */
 	evsel = perf_evsel__next(evsel);
@@ -543,6 +544,7 @@ static int test__group1(struct perf_evlist *evlist)
 	TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2);
 	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	return 0;
 }
@@ -568,6 +570,7 @@ static int test__group2(struct perf_evlist *evlist)
 	TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
 	TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	/* cache-references + :u modifier */
 	evsel = perf_evsel__next(evsel);
@@ -582,6 +585,7 @@ static int test__group2(struct perf_evlist *evlist)
 	TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
 	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	/* cycles:k */
 	evsel = perf_evsel__next(evsel);
@@ -595,6 +599,7 @@ static int test__group2(struct perf_evlist *evlist)
 	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
 	TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
 	TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	return 0;
 }
@@ -623,6 +628,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused)
 		!strcmp(leader->group_name, "group1"));
 	TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	/* group1 cycles:kppp */
 	evsel = perf_evsel__next(evsel);
@@ -639,6 +645,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused)
 	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
 	TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	/* group2 cycles + G modifier */
 	evsel = leader = perf_evsel__next(evsel);
@@ -656,6 +663,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused)
 		!strcmp(leader->group_name, "group2"));
 	TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	/* group2 1:3 + G modifier */
 	evsel = perf_evsel__next(evsel);
@@ -669,6 +677,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused)
 	TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
 	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	/* instructions:u */
 	evsel = perf_evsel__next(evsel);
@@ -682,6 +691,7 @@ static int test__group3(struct perf_evlist *evlist __maybe_unused)
 	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
 	TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
 	TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	return 0;
 }
@@ -709,6 +719,7 @@ static int test__group4(struct perf_evlist *evlist __maybe_unused)
 	TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
 	TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	/* instructions:kp + p */
 	evsel = perf_evsel__next(evsel);
@@ -724,6 +735,7 @@ static int test__group4(struct perf_evlist *evlist __maybe_unused)
 	TEST_ASSERT_VAL("wrong precise_ip", evsel->attr.precise_ip == 2);
 	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	return 0;
 }
@@ -750,6 +762,7 @@ static int test__group5(struct perf_evlist *evlist __maybe_unused)
 	TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
 	TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	/* instructions + G */
 	evsel = perf_evsel__next(evsel);
@@ -764,6 +777,7 @@ static int test__group5(struct perf_evlist *evlist __maybe_unused)
 	TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
 	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 1);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	/* cycles:G */
 	evsel = leader = perf_evsel__next(evsel);
@@ -780,6 +794,7 @@ static int test__group5(struct perf_evlist *evlist __maybe_unused)
 	TEST_ASSERT_VAL("wrong leader", perf_evsel__is_group_leader(evsel));
 	TEST_ASSERT_VAL("wrong nr_members", evsel->nr_members == 2);
 	TEST_ASSERT_VAL("wrong group_idx", perf_evsel__group_idx(evsel) == 0);
+	TEST_ASSERT_VAL("wrong sample_read", !evsel->sample_read);
 
 	/* instructions:G */
 	evsel = perf_evsel__next(evsel);
@@ -971,6 +986,98 @@ static int test__group_gh4(struct perf_evlist *evlist)
 	return 0;
 }
 
+static int test__leader_sample1(struct perf_evlist *evlist)
+{
+	struct perf_evsel *evsel, *leader;
+
+	TEST_ASSERT_VAL("wrong number of entries", 3 == evlist->nr_entries);
+
+	/* cycles - sampling group leader */
+	evsel = leader = perf_evlist__first(evlist);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
+	TEST_ASSERT_VAL("wrong config",
+			PERF_COUNT_HW_CPU_CYCLES == evsel->attr.config);
+	TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
+	TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
+	TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
+	TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
+	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
+	TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
+	TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+	TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read);
+
+	/* cache-misses - not sampling */
+	evsel = perf_evsel__next(evsel);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
+	TEST_ASSERT_VAL("wrong config",
+			PERF_COUNT_HW_CACHE_MISSES == evsel->attr.config);
+	TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
+	TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
+	TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
+	TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
+	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
+	TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+	TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read);
+
+	/* branch-misses - not sampling */
+	evsel = perf_evsel__next(evsel);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
+	TEST_ASSERT_VAL("wrong config",
+			PERF_COUNT_HW_BRANCH_MISSES == evsel->attr.config);
+	TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
+	TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel);
+	TEST_ASSERT_VAL("wrong exclude_hv", !evsel->attr.exclude_hv);
+	TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
+	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
+	TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
+	TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+	TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read);
+
+	return 0;
+}
+
+static int test__leader_sample2(struct perf_evlist *evlist __maybe_unused)
+{
+	struct perf_evsel *evsel, *leader;
+
+	TEST_ASSERT_VAL("wrong number of entries", 2 == evlist->nr_entries);
+
+	/* instructions - sampling group leader */
+	evsel = leader = perf_evlist__first(evlist);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
+	TEST_ASSERT_VAL("wrong config",
+			PERF_COUNT_HW_INSTRUCTIONS == evsel->attr.config);
+	TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
+	TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
+	TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
+	TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
+	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
+	TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
+	TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+	TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read);
+
+	/* branch-misses - not sampling */
+	evsel = perf_evsel__next(evsel);
+	TEST_ASSERT_VAL("wrong type", PERF_TYPE_HARDWARE == evsel->attr.type);
+	TEST_ASSERT_VAL("wrong config",
+			PERF_COUNT_HW_BRANCH_MISSES == evsel->attr.config);
+	TEST_ASSERT_VAL("wrong exclude_user", !evsel->attr.exclude_user);
+	TEST_ASSERT_VAL("wrong exclude_kernel", evsel->attr.exclude_kernel);
+	TEST_ASSERT_VAL("wrong exclude_hv", evsel->attr.exclude_hv);
+	TEST_ASSERT_VAL("wrong exclude guest", evsel->attr.exclude_guest);
+	TEST_ASSERT_VAL("wrong exclude host", !evsel->attr.exclude_host);
+	TEST_ASSERT_VAL("wrong precise_ip", !evsel->attr.precise_ip);
+	TEST_ASSERT_VAL("wrong group name", !evsel->group_name);
+	TEST_ASSERT_VAL("wrong leader", evsel->leader == leader);
+	TEST_ASSERT_VAL("wrong sample_read", evsel->sample_read);
+
+	return 0;
+}
+
 static int count_tracepoints(void)
 {
 	char events_path[PATH_MAX];
@@ -1187,6 +1294,14 @@ static struct evlist_test test__events[] = {
 		.name  = "{cycles:G,cache-misses:H}:uG",
 		.check = test__group_gh4,
 	},
+	[38] = {
+		.name  = "{cycles,cache-misses,branch-misses}:S",
+		.check = test__leader_sample1,
+	},
+	[39] = {
+		.name  = "{instructions,branch-misses}:Su",
+		.check = test__leader_sample2,
+	},
 };
 
 static struct evlist_test test__events_pmu[] = {
-- 
1.7.11.7


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

* Re: [PATCH 01/11] perf ui/hist: Add support to display whole group data for raw columns
  2013-02-04 12:32 ` [PATCH 01/11] perf ui/hist: Add support to display whole group data for raw columns Jiri Olsa
@ 2013-02-06  4:41   ` Namhyung Kim
  2013-02-06 22:10   ` [tip:perf/core] perf hists browser: " tip-bot for Jiri Olsa
  1 sibling, 0 replies; 17+ messages in thread
From: Namhyung Kim @ 2013-02-06  4:41 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Peter Zijlstra,
	Ingo Molnar, Paul Mackerras, Corey Ashford, Frederic Weisbecker

Hi Jiri,

On Mon,  4 Feb 2013 13:32:55 +0100, Jiri Olsa wrote:
> Currently we don't display group members' values for raw
> columns like 'Samples' and 'Period' when in group report
> mode.

Oops, it was lost during the rework.  Thanks for fixing this.

Thanks,
Namhyung

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

* Re: [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support
  2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
                   ` (10 preceding siblings ...)
  2013-02-04 12:33 ` [PATCH 11/11] perf tests: Add parse events tests for leader sampling Jiri Olsa
@ 2013-02-06  4:59 ` Namhyung Kim
  11 siblings, 0 replies; 17+ messages in thread
From: Namhyung Kim @ 2013-02-06  4:59 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Peter Zijlstra,
	Ingo Molnar, Paul Mackerras, Corey Ashford, Frederic Weisbecker

On Mon,  4 Feb 2013 13:32:54 +0100, Jiri Olsa wrote:
> hi,
> adding support to read sample values through the PERF_SAMPLE_READ
> sample type. It's now possible to specify 'S' modifier for an event
> and get its sample value by PERF_SAMPLE_READ.
>
> For group the 'S' modifier will enable sampling only for the leader
> and read all the group member by PERF_SAMPLE_READ smple type with
> PERF_FORMAT_GROUP read format.
>
> This was first introduced in here:
> https://lkml.org/lkml/2012/10/20/75
>
> Example:
>
>   $ perf record -e '{cycles,cache-misses}:S' ls
>   ...
>   $ perf report --group --show-total-period --stdio
>   ...
>   # Samples: 36  of event 'anon group { cycles, cache-misses }'
>   # Event count (approx.): 12585593
>   #
>   #         Overhead                    Period  Command      Shared Object                      Symbol
>   # ................  ........................  .......  .................  ..........................
>   #
>       19.92%   1.20%       2505936          31       ls  [kernel.kallsyms]  [k] mark_held_locks
>       13.74%   0.47%       1729327          12       ls  [kernel.kallsyms]  [k] sched_clock_local
>       13.64%  23.72%       1716147         612       ls  ld-2.14.90.so      [.] check_match.10805
>       13.12%  23.22%       1650778         599       ls  libc-2.14.90.so    [.] _nl_intern_locale_data
>       11.24%  29.19%       1414554         753       ls  [kernel.kallsyms]  [k] sched_clock_cpu
>        8.50%   0.35%       1070150           9       ls  [kernel.kallsyms]  [k] check_chain_key
>   ...
>
>
> The patchset is based on following fix:
> http://lkml.org/lkml/2013/2/4/122
>
> and is available also at:
> git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/linux.git
> perf/group6

For the whole series:

  Acked-by: Namhyung Kim <namhyung@kernel.org>

Thanks,
Namhyung

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

* [tip:perf/core] perf hists browser: Add support to display whole group data for raw columns
  2013-02-04 12:32 ` [PATCH 01/11] perf ui/hist: Add support to display whole group data for raw columns Jiri Olsa
  2013-02-06  4:41   ` Namhyung Kim
@ 2013-02-06 22:10   ` tip-bot for Jiri Olsa
  1 sibling, 0 replies; 17+ messages in thread
From: tip-bot for Jiri Olsa @ 2013-02-06 22:10 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, a.p.zijlstra, namhyung,
	jolsa, fweisbec, tglx, cjashfor, mingo

Commit-ID:  0c5268bf2218144469dde3228f14898fadbbcdcd
Gitweb:     http://git.kernel.org/tip/0c5268bf2218144469dde3228f14898fadbbcdcd
Author:     Jiri Olsa <jolsa@redhat.com>
AuthorDate: Mon, 4 Feb 2013 13:32:55 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Wed, 6 Feb 2013 18:09:27 -0300

perf hists browser: Add support to display whole group data for raw columns

Currently we don't display group members' values for raw columns like
'Samples' and 'Period' when in group report mode.

Uniting '__hpp__percent_fmt' and '__hpp__raw_fmt' function under new
function __hpp__fmt. It's basically '__hpp__percent_fmt' code with new
'fmt_percent' bool parameter added saying whether raw number or
percentage should be printed.

This way raw columns print out all the group members when
in group report mode, like:

  $ perf record -e '{cycles,cache-misses}' ls
  ...
  $ perf report --group --show-total-period --stdio
  ...
  #         Overhead                    Period  Command      Shared Object                             Symbol
  # ................  ........................  .......  .................  .................................
  #
      23.63%  11.24%       3331335         317       ls  [kernel.kallsyms]  [k] __lock_acquire
      12.72%   0.00%       1793100           0       ls  [kernel.kallsyms]  [k] native_sched_clock
       9.72%   0.00%       1369920           0       ls  libc-2.14.90.so    [.] _nl_find_locale
       0.03%   0.07%          4476           2       ls  [kernel.kallsyms]  [k] intel_pmu_enable_all
       0.00%  11.73%             0         331       ls  ld-2.14.90.so      [.] _dl_cache_libcmp
       0.00%  11.06%             0         312       ls  [kernel.kallsyms]  [k] vma_interval_tree_insert

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1359981185-16819-2-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/ui/hist.c | 53 ++++++++++++++++++++++++++--------------------------
 1 file changed, 26 insertions(+), 27 deletions(-)

diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index a47ce98..d671e63 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -9,18 +9,24 @@
 
 typedef int (*hpp_snprint_fn)(char *buf, size_t size, const char *fmt, ...);
 
-static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he,
-			      u64 (*get_field)(struct hist_entry *),
-			      const char *fmt, hpp_snprint_fn print_fn)
+static int __hpp__fmt(struct perf_hpp *hpp, struct hist_entry *he,
+		      u64 (*get_field)(struct hist_entry *),
+		      const char *fmt, hpp_snprint_fn print_fn,
+		      bool fmt_percent)
 {
 	int ret;
-	double percent = 0.0;
 	struct hists *hists = he->hists;
 
-	if (hists->stats.total_period)
-		percent = 100.0 * get_field(he) / hists->stats.total_period;
+	if (fmt_percent) {
+		double percent = 0.0;
+
+		if (hists->stats.total_period)
+			percent = 100.0 * get_field(he) /
+				  hists->stats.total_period;
 
-	ret = print_fn(hpp->buf, hpp->size, fmt, percent);
+		ret = print_fn(hpp->buf, hpp->size, fmt, percent);
+	} else
+		ret = print_fn(hpp->buf, hpp->size, fmt, get_field(he));
 
 	if (symbol_conf.event_group) {
 		int prev_idx, idx_delta;
@@ -49,11 +55,15 @@ static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he,
 				 * have no sample
 				 */
 				ret += print_fn(hpp->buf + ret, hpp->size - ret,
-						fmt, 0.0);
+						fmt, 0);
 			}
 
-			ret += print_fn(hpp->buf + ret, hpp->size - ret,
-					fmt, 100.0 * period / total);
+			if (fmt_percent)
+				ret += print_fn(hpp->buf + ret, hpp->size - ret,
+						fmt, 100.0 * period / total);
+			else
+				ret += print_fn(hpp->buf + ret, hpp->size - ret,
+						fmt, period);
 
 			prev_idx = perf_evsel__group_idx(evsel);
 		}
@@ -65,23 +75,12 @@ static int __hpp__percent_fmt(struct perf_hpp *hpp, struct hist_entry *he,
 			 * zero-fill group members at last which have no sample
 			 */
 			ret += print_fn(hpp->buf + ret, hpp->size - ret,
-					fmt, 0.0);
+					fmt, 0);
 		}
 	}
 	return ret;
 }
 
-static int __hpp__raw_fmt(struct perf_hpp *hpp, struct hist_entry *he,
-			  u64 (*get_field)(struct hist_entry *),
-			  const char *fmt, hpp_snprint_fn print_fn)
-{
-	int ret;
-
-	ret = print_fn(hpp->buf, hpp->size, fmt, get_field(he));
-	return ret;
-}
-
-
 #define __HPP_HEADER_FN(_type, _str, _min_width, _unit_width) 		\
 static int hpp__header_##_type(struct perf_hpp *hpp)			\
 {									\
@@ -116,16 +115,16 @@ static u64 he_get_##_field(struct hist_entry *he)				\
 										\
 static int hpp__color_##_type(struct perf_hpp *hpp, struct hist_entry *he) 	\
 {										\
-	return __hpp__percent_fmt(hpp, he, he_get_##_field, " %6.2f%%",		\
-				  (hpp_snprint_fn)percent_color_snprintf); 	\
+	return __hpp__fmt(hpp, he, he_get_##_field, " %6.2f%%",			\
+			  (hpp_snprint_fn)percent_color_snprintf, true);	\
 }
 
 #define __HPP_ENTRY_PERCENT_FN(_type, _field)					\
 static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) 	\
 {										\
 	const char *fmt = symbol_conf.field_sep ? " %.2f" : " %6.2f%%";		\
-	return __hpp__percent_fmt(hpp, he, he_get_##_field, fmt,		\
-				  scnprintf);					\
+	return __hpp__fmt(hpp, he, he_get_##_field, fmt,			\
+			  scnprintf, true);					\
 }
 
 #define __HPP_ENTRY_RAW_FN(_type, _field)					\
@@ -137,7 +136,7 @@ static u64 he_get_raw_##_field(struct hist_entry *he)				\
 static int hpp__entry_##_type(struct perf_hpp *hpp, struct hist_entry *he) 	\
 {										\
 	const char *fmt = symbol_conf.field_sep ? " %"PRIu64 : " %11"PRIu64;	\
-	return __hpp__raw_fmt(hpp, he, he_get_raw_##_field, fmt, scnprintf);	\
+	return __hpp__fmt(hpp, he, he_get_raw_##_field, fmt, scnprintf, false);	\
 }
 
 #define HPP_PERCENT_FNS(_type, _str, _field, _min_width, _unit_width)	\

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

* Re: [PATCH 02/11] perf: Add PERF_EVENT_IOC_ID ioctl to return event ID
  2013-02-04 12:32 ` [PATCH 02/11] perf: Add PERF_EVENT_IOC_ID ioctl to return event ID Jiri Olsa
@ 2013-05-02 13:38   ` Peter Zijlstra
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Zijlstra @ 2013-05-02 13:38 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Peter Zijlstra,
	Ingo Molnar, Paul Mackerras, Corey Ashford, Frederic Weisbecker,
	Namhyung Kim

On Mon, Feb 04, 2013 at 01:32:56PM +0100, Jiri Olsa wrote:
> From: "jolsa@redhat.com" <jolsa@redhat.com>
> 
> The only way to get the event ID is by reading the event fd,
> followed by parsing the ID value out of the returned data.
> 
> While this is ok for current read format used by perf tool,
> it is not ok when we use PERF_FORMAT_GROUP format.
> 
> With this format the data are returned for the whole group
> and there's no way to find out what ID belongs to our fd
> (if we are not group leader event).
> 
> Adding a simple ioctl that returns event primary ID for given fd.
> 
> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>

Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>

> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> ---
>  include/uapi/linux/perf_event.h | 1 +
>  kernel/events/core.c            | 9 +++++++++
>  2 files changed, 10 insertions(+)
> 
> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
> index 9fa9c62..b4ea8ed 100644
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -316,6 +316,7 @@ struct perf_event_attr {
>  #define PERF_EVENT_IOC_PERIOD		_IOW('$', 4, __u64)
>  #define PERF_EVENT_IOC_SET_OUTPUT	_IO ('$', 5)
>  #define PERF_EVENT_IOC_SET_FILTER	_IOW('$', 6, char *)
> +#define PERF_EVENT_IOC_ID		_IOR('$', 7, u64 *)
>  
>  enum perf_event_ioc_flags {
>  	PERF_IOC_FLAG_GROUP		= 1U << 0,
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 301079d..4081261 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -3277,6 +3277,15 @@ static long perf_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
>  	case PERF_EVENT_IOC_PERIOD:
>  		return perf_event_period(event, (u64 __user *)arg);
>  
> +	case PERF_EVENT_IOC_ID:
> +	{
> +		u64 id = primary_event_id(event);
> +
> +		if (copy_to_user((void __user *)arg, &id, sizeof(id)))
> +			return -EFAULT;
> +		return 0;
> +	}
> +
>  	case PERF_EVENT_IOC_SET_OUTPUT:
>  	{
>  		int ret;
> -- 
> 1.7.11.7
> 

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

* Re: [PATCH 03/11] perf: Do not get values from disabled counters in group format read
  2013-02-04 12:32 ` [PATCH 03/11] perf: Do not get values from disabled counters in group format read Jiri Olsa
@ 2013-05-02 13:39   ` Peter Zijlstra
  0 siblings, 0 replies; 17+ messages in thread
From: Peter Zijlstra @ 2013-05-02 13:39 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Peter Zijlstra,
	Ingo Molnar, Paul Mackerras, Corey Ashford, Frederic Weisbecker,
	Namhyung Kim

On Mon, Feb 04, 2013 at 01:32:57PM +0100, Jiri Olsa wrote:
> From: "jolsa@redhat.com" <jolsa@redhat.com>
> 
> It's possible some of the counters in the group could be
> disabled when sampling member of the event group is reading
> the rest via PERF_SAMPLE_READ sample type processing. Disabled
> counters could then produce wrong numbers.
> 
> Fixing that by reading only enabled counters for PERF_SAMPLE_READ
> sample type processing.
> 
> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>

I had to like re-read our previous thread on this; which I think says that the
Changelog isn't perfect. However:

Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>

> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> ---
>  kernel/events/core.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 4081261..e2ea1b9 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -4018,7 +4018,8 @@ static void perf_output_read_group(struct perf_output_handle *handle,
>  	list_for_each_entry(sub, &leader->sibling_list, group_entry) {
>  		n = 0;
>  
> -		if (sub != event)
> +		if ((sub != event) &&
> +		    (sub->state == PERF_EVENT_STATE_ACTIVE))
>  			sub->pmu->read(sub);
>  
>  		values[n++] = perf_event_count(sub);
> -- 
> 1.7.11.7
> 

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

end of thread, other threads:[~2013-05-02 13:41 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-04 12:32 [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Jiri Olsa
2013-02-04 12:32 ` [PATCH 01/11] perf ui/hist: Add support to display whole group data for raw columns Jiri Olsa
2013-02-06  4:41   ` Namhyung Kim
2013-02-06 22:10   ` [tip:perf/core] perf hists browser: " tip-bot for Jiri Olsa
2013-02-04 12:32 ` [PATCH 02/11] perf: Add PERF_EVENT_IOC_ID ioctl to return event ID Jiri Olsa
2013-05-02 13:38   ` Peter Zijlstra
2013-02-04 12:32 ` [PATCH 03/11] perf: Do not get values from disabled counters in group format read Jiri Olsa
2013-05-02 13:39   ` Peter Zijlstra
2013-02-04 12:32 ` [PATCH 04/11] perf tools: Use PERF_EVENT_IOC_ID perf ioctl to read event id Jiri Olsa
2013-02-04 12:32 ` [PATCH 05/11] perf tools: Add support for parsing PERF_SAMPLE_READ sample type Jiri Olsa
2013-02-04 12:33 ` [PATCH 06/11] perf tools: Fix event ID retrieval for group format read case Jiri Olsa
2013-02-04 12:33 ` [PATCH 07/11] perf tools: Add perf_evlist__id2sid function to get event ID related data Jiri Olsa
2013-02-04 12:33 ` [PATCH 08/11] perf tools: Add PERF_SAMPLE_READ sample related processing Jiri Olsa
2013-02-04 12:33 ` [PATCH 09/11] perf tools: Add 'S' event/group modifier to read sample value Jiri Olsa
2013-02-04 12:33 ` [PATCH 10/11] perf tests: Add attr record group sampling test Jiri Olsa
2013-02-04 12:33 ` [PATCH 11/11] perf tests: Add parse events tests for leader sampling Jiri Olsa
2013-02-06  4:59 ` [PATCH 00/11] perf tool: Add PERF_SAMPLE_READ sample read support Namhyung Kim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).