[PATCH RFC 02/10] perf,tools: Enable counter statistic read for perf record

From: kan . liang
Date: Tue Sep 22 2015 - 17:33:47 EST


From: Kan Liang <kan.liang@xxxxxxxxx>

Using 'C' event/group modifier to specify the event which want to read
counter statistics during sampling. For this event, the sampling will
be disabled.
The 'C' modifier only be available on system-wide/CPU mode. If a
group is marked as 'C' modifier, only group members read counter
statistics. Group leader always do sampling.
The other limit is that the first event cannot be counter statistics
read event, since many tools special handle first event.

Signed-off-by: Kan Liang <kan.liang@xxxxxxxxx>
---
tools/perf/Documentation/perf-list.txt | 5 +++++
tools/perf/util/evlist.c | 3 +++
tools/perf/util/evsel.c | 29 +++++++++++++++++++++++++++++
tools/perf/util/record.c | 6 ++++--
4 files changed, 41 insertions(+), 2 deletions(-)

diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt
index bada893..a409fc9 100644
--- a/tools/perf/Documentation/perf-list.txt
+++ b/tools/perf/Documentation/perf-list.txt
@@ -31,6 +31,11 @@ counted. The following modifiers exist:
H - host counting (not in KVM guests)
p - precise level
S - read sample value (PERF_SAMPLE_READ)
+ C - read counter statistics during sampling (Can be used to read
+ counter statistics of PMU_A event when PMU_B events are sampling.
+ For example, getting memory bandwidth by uncore events during the
+ CPU PMU events run time)
+ (Only available for group members or non-first event in system-wide/CPU mode)
D - pin the event to the PMU

The 'p' modifier can be used for specifying how precise the instruction
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index a864373..603ee3e 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -885,6 +885,9 @@ static int perf_evlist__mmap_per_evsel(struct perf_evlist *evlist, int idx,
if (evsel->system_wide && thread)
continue;

+ if (evsel->counter_read)
+ continue;
+
fd = FD(evsel, cpu, thread);

if (*output == -1) {
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 5889004..8c18422 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -724,6 +724,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
struct perf_event_attr *attr = &evsel->attr;
int track = evsel->tracking;
bool per_cpu = opts->target.default_per_cpu && !opts->target.per_thread;
+ struct perf_evsel *first = perf_evlist__first(evsel->evlist);

attr->sample_id_all = perf_missing_features.sample_id_all ? 0 : 1;
attr->inherit = !opts->no_inherit;
@@ -882,6 +883,34 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts)
attr->clockid = opts->clockid;
}

+ if (evsel->counter_read) {
+ if (!target__has_cpu(&opts->target)) {
+ evsel->counter_read = 0;
+ ui__warning("Counter statistics read only available "
+ "on system-wide/CPU mode.\n"
+ "Remove :C modifier for event %s\n",
+ evsel->name);
+ } else {
+ /* Don't do counter read for Group leader */
+ if ((evsel->leader == evsel) && (evsel->leader->nr_members > 1)) {
+ evsel->counter_read = 0;
+ } else {
+ if (first == evsel) {
+ evsel->counter_read = 0;
+ ui__warning("The first event cannot be counter read event"
+ "Remove :C modifier for event %s\n",
+ evsel->name);
+ } else {
+ attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
+ PERF_FORMAT_TOTAL_TIME_RUNNING;
+ attr->sample_freq = 0;
+ attr->sample_period = 0;
+ attr->sample_type = 0;
+ evsel->sample_size = 0;
+ }
+ }
+ }
+ }
/*
* Apply event specific term settings,
* it overloads any global configuration.
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index 0467367..9ede1f7 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -171,8 +171,10 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
use_sample_identifier = perf_can_sample_identifier();
break;
}
- evlist__for_each(evlist, evsel)
- perf_evsel__set_sample_id(evsel, use_sample_identifier);
+ evlist__for_each(evlist, evsel) {
+ if (!evsel->counter_read)
+ perf_evsel__set_sample_id(evsel, use_sample_identifier);
+ }
}

perf_evlist__set_id_pos(evlist);
--
1.8.3.1

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