[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20150126164943.GA10207@kernel.org>
Date: Mon, 26 Jan 2015 13:49:43 -0300
From: Arnaldo Carvalho de Melo <acme@...nel.org>
To: Stephane Eranian <eranian@...gle.com>
Cc: Adrian Hunter <adrian.hunter@...el.com>,
Ingo Molnar <mingo@...nel.org>,
Andi Kleen <ak@...ux.intel.com>, Borislav Petkov <bp@...e.de>,
David Ahern <dsahern@...il.com>,
Don Zickus <dzickus@...hat.com>,
Frederic Weisbecker <fweisbec@...il.com>,
Jiri Olsa <jolsa@...hat.com>,
Namhyung Kim <namhyung@...nel.org>, Yan@...radead.org,
Zheng <zheng.z.yan@...el.com>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>
Subject: [RFC/PATCH 1/1] perf evsel: Set evsel->cpus to the evlist->cpus when
not constrained
Stephane,
Following up on that private discussion, can you take a look?
- Arnaldo
>From 9ecdd9b9bf0a7fd5645957ba4e6a98b6ee526109 Mon Sep 17 00:00:00 2001
From: Arnaldo Carvalho de Melo <acme@...hat.com>
Date: Mon, 26 Jan 2015 13:43:42 -0300
Subject: [PATCH 1/1] perf evsel: Set evsel->cpus to the evlist->cpus when not
constrained
So that we don't need to know about the evlist all the time and can cope
with cases where evsel->cpus were set because it was for an event on a
PMU with a cpumask.
Reported-by: Stephane Eranian <eranian@...gle.com>
Cc: Adrian Hunter <adrian.hunter@...el.com>
Cc: Andi Kleen <ak@...ux.intel.com>
Cc: Borislav Petkov <bp@...e.de>
Cc: David Ahern <dsahern@...il.com>
Cc: Don Zickus <dzickus@...hat.com>
Cc: Frederic Weisbecker <fweisbec@...il.com>
Cc: Jiri Olsa <jolsa@...hat.com>
Cc: Namhyung Kim <namhyung@...nel.org>
Cc: Yan, Zheng <zheng.z.yan@...el.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@...hat.com>
---
tools/perf/builtin-stat.c | 36 ++++++++++------------------
tools/perf/util/evlist.c | 61 ++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 66 insertions(+), 31 deletions(-)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e598e4e98170..ddf41bede0b8 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -163,16 +163,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;
@@ -202,7 +192,7 @@ static int perf_evsel__alloc_prev_raw_counts(struct perf_evsel *evsel)
size_t sz;
sz = sizeof(*evsel->counts) +
- (perf_evsel__nr_cpus(evsel) * sizeof(struct perf_counts_values));
+ (cpu_map__nr(evsel->cpus) * sizeof(struct perf_counts_values));
addr = zalloc(sz);
if (!addr)
@@ -235,7 +225,7 @@ static int perf_evlist__alloc_stats(struct perf_evlist *evlist, bool alloc_raw)
evlist__for_each(evlist, evsel) {
if (perf_evsel__alloc_stat_priv(evsel) < 0 ||
- perf_evsel__alloc_counts(evsel, perf_evsel__nr_cpus(evsel)) < 0 ||
+ perf_evsel__alloc_counts(evsel, cpu_map__nr(evsel->cpus)) < 0 ||
(alloc_raw && perf_evsel__alloc_prev_raw_counts(evsel) < 0))
goto out_free;
}
@@ -269,7 +259,7 @@ static void perf_stat__reset_stats(struct perf_evlist *evlist)
evlist__for_each(evlist, evsel) {
perf_evsel__reset_stat_priv(evsel);
- perf_evsel__reset_counts(evsel, perf_evsel__nr_cpus(evsel));
+ perf_evsel__reset_counts(evsel, cpu_map__nr(evsel->cpus));
}
memset(runtime_nsecs_stats, 0, sizeof(runtime_nsecs_stats));
@@ -302,7 +292,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
attr->inherit = !no_inherit;
if (target__has_cpu(&target))
- return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
+ return perf_evsel__open_per_cpu(evsel, evsel->cpus);
if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) {
attr->disabled = 1;
@@ -397,7 +387,7 @@ static void zero_per_pkg(struct perf_evsel *counter)
static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip)
{
unsigned long *mask = counter->per_pkg_mask;
- struct cpu_map *cpus = perf_evsel__cpus(counter);
+ struct cpu_map *cpus = counter->cpus;
int s;
*skip = false;
@@ -507,7 +497,7 @@ static int read_counter_aggr(struct perf_evsel *counter)
static int read_counter(struct perf_evsel *counter)
{
int nthreads = thread_map__nr(evsel_list->threads);
- int ncpus = perf_evsel__nr_cpus(counter);
+ int ncpus = cpu_map__nr(counter->cpus);
int cpu, thread;
if (counter->system_wide)
@@ -727,13 +717,13 @@ static int __run_perf_stat(int argc, const char **argv)
if (aggr_mode == AGGR_GLOBAL) {
evlist__for_each(evsel_list, counter) {
read_counter_aggr(counter);
- perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter),
+ perf_evsel__close_fd(counter, cpu_map__nr(counter->cpus),
thread_map__nr(evsel_list->threads));
}
} else {
evlist__for_each(evsel_list, counter) {
read_counter(counter);
- perf_evsel__close_fd(counter, perf_evsel__nr_cpus(counter), 1);
+ perf_evsel__close_fd(counter, cpu_map__nr(counter->cpus), 1);
}
}
@@ -812,7 +802,7 @@ static void aggr_printout(struct perf_evsel *evsel, int id, int nr)
case AGGR_NONE:
fprintf(output, "CPU%*d%s",
csv_output ? 0 : -4,
- perf_evsel__cpus(evsel)->map[id], csv_sep);
+ evsel->cpus->map[id], csv_sep);
break;
case AGGR_GLOBAL:
default:
@@ -1216,8 +1206,8 @@ static void print_aggr(char *prefix)
evlist__for_each(evsel_list, counter) {
val = ena = run = 0;
nr = 0;
- for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
- cpu2 = perf_evsel__cpus(counter)->map[cpu];
+ for (cpu = 0; cpu < cpu_map__nr(counter->cpus); cpu++) {
+ cpu2 = counter->cpus->map[cpu];
s2 = aggr_get_id(evsel_list->cpus, cpu2);
if (s2 != id)
continue;
@@ -1339,7 +1329,7 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
double uval;
int cpu;
- for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
+ for (cpu = 0; cpu < cpu_map__nr(counter->cpus); cpu++) {
val = counter->counts->cpu[cpu].val;
ena = counter->counts->cpu[cpu].ena;
run = counter->counts->cpu[cpu].run;
@@ -1350,7 +1340,7 @@ static void print_counter(struct perf_evsel *counter, char *prefix)
if (run == 0 || ena == 0) {
fprintf(output, "CPU%*d%s%*s%s",
csv_output ? 0 : -4,
- perf_evsel__cpus(counter)->map[cpu], csv_sep,
+ counter->cpus->map[cpu], csv_sep,
csv_output ? 0 : 18,
counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED,
csv_sep);
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 28b8ce86bf12..202d1e9842e7 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -111,13 +111,45 @@ void perf_evlist__exit(struct perf_evlist *evlist)
fdarray__exit(&evlist->pollfd);
}
+static void perf_evlist__reset_cpus(struct perf_evlist *evlist)
+{
+ struct perf_evsel *evsel;
+
+ evlist__for_each(evlist, evsel) {
+ if (evsel->cpus == evlist->cpus)
+ evsel->cpus = NULL;
+ }
+
+ evlist->cpus = NULL;
+}
+
+static void perf_evlist__set_cpus(struct perf_evlist *evlist, struct cpu_map *cpus)
+{
+ struct perf_evsel *evsel;
+
+ if (evlist->cpus != NULL)
+ perf_evlist__reset_cpus(evlist);
+ /*
+ * If, when parsing events, the evsel->cpus wasn't constrained to a
+ * cpulist, say, because it is on a PMU that has a cpumask, then set it
+ * to the evlist cpu_map, so that we can access evsel->cpus and get the
+ * cpu_map this evsel works with.
+ */
+ evlist__for_each(evlist, evsel) {
+ if (evsel->cpus == NULL)
+ evsel->cpus = cpus;
+ }
+
+ evlist->cpus = cpus;
+}
+
void perf_evlist__delete(struct perf_evlist *evlist)
{
perf_evlist__munmap(evlist);
perf_evlist__close(evlist);
cpu_map__delete(evlist->cpus);
+ perf_evlist__reset_cpus(evlist);
thread_map__delete(evlist->threads);
- evlist->cpus = NULL;
evlist->threads = NULL;
perf_evlist__purge(evlist);
perf_evlist__exit(evlist);
@@ -129,6 +161,14 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
list_add_tail(&entry->node, &evlist->entries);
entry->idx = evlist->nr_entries;
entry->tracking = !entry->idx;
+ /*
+ * If, when parsing events, the evsel->cpus wasn't constrained to a
+ * cpulist, say, because it is on a PMU that has a cpumask, then set it
+ * to the evlist cpu_map, so that we can access evsel->cpus and get the
+ * cpu_map this evsel works with.
+ */
+ if (entry->cpus == NULL)
+ entry->cpus = evlist->cpus;
if (!evlist->nr_entries++)
perf_evlist__set_id_pos(evlist);
@@ -1029,6 +1069,8 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
{
+ struct cpu_map *cpus;
+
evlist->threads = thread_map__new_str(target->pid, target->tid,
target->uid);
@@ -1036,13 +1078,15 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
return -1;
if (target__uses_dummy_map(target))
- evlist->cpus = cpu_map__dummy_new();
+ cpus = cpu_map__dummy_new();
else
- evlist->cpus = cpu_map__new(target->cpu_list);
+ cpus = cpu_map__new(target->cpu_list);
- if (evlist->cpus == NULL)
+ if (cpus == NULL)
goto out_delete_threads;
+ perf_evlist__set_cpus(evlist, cpus);
+
return 0;
out_delete_threads:
@@ -1222,6 +1266,7 @@ void perf_evlist__close(struct perf_evlist *evlist)
static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist)
{
+ struct cpu_map *cpus;
int err = -ENOMEM;
/*
@@ -1233,20 +1278,20 @@ static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist)
* error, and we may not want to do that fallback to a
* default cpu identity map :-\
*/
- evlist->cpus = cpu_map__new(NULL);
- if (evlist->cpus == NULL)
+ cpus = cpu_map__new(NULL);
+ if (cpus == NULL)
goto out;
evlist->threads = thread_map__new_dummy();
if (evlist->threads == NULL)
goto out_free_cpus;
+ perf_evlist__set_cpus(evlist, cpus);
err = 0;
out:
return err;
out_free_cpus:
- cpu_map__delete(evlist->cpus);
- evlist->cpus = NULL;
+ cpu_map__delete(cpus);
goto out;
}
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists