On old kernels that don't support sample_id_all feature,
perf_evlist__id2evsel() returns NULL for non-sampling events.
This breaks perf top when multiple events are given on command
line. Fix it by using first evsel in the evlist. This will also
prevent getting the same (potential) problem in such new tool/
old kernel combo.
Suggested-by: Arnaldo Carvalho de Melo <[email protected]>
Signed-off-by: Namhyung Kim <[email protected]>
---
tools/perf/util/evlist.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 5c61dc57d7c7..f8da9fada002 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -349,6 +349,10 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
hlist_for_each_entry(sid, pos, head, node)
if (sid->id == id)
return sid->evsel;
+
+ if (!perf_evlist__sample_id_all(evlist))
+ return list_entry(evlist->entries.next, struct perf_evsel, node);
+
return NULL;
}
--
1.7.9
When a user tries to open so many event on multiple tasks/cpus,
perf_event_open syscall may fail with EMFILE. Provide an advice
for that case.
Signed-off-by: Namhyung Kim <[email protected]>
Cc: David Ahern <[email protected]>
---
tools/perf/builtin-record.c | 5 +++++
tools/perf/builtin-stat.c | 4 ++++
tools/perf/builtin-top.c | 3 ++-
3 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 75d230fef202..b1112084a0ae 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -260,6 +260,11 @@ try_again:
ui__warning("The %s event is not supported.\n",
event_name(pos));
exit(EXIT_FAILURE);
+ } else if (err == EMFILE) {
+ ui__warning("Too many events are opened.\n"
+ "Try again after reducing the number of events,\n"
+ "tasks and/or cpus.\n");
+ exit(EXIT_FAILURE);
}
printf("\n");
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index ea40e4e8b227..e54cbc9fc4fd 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -477,6 +477,10 @@ static int run_perf_stat(int argc __used, const char **argv)
"\t Consider tweaking"
" /proc/sys/kernel/perf_event_paranoid or running as root.",
system_wide ? "system-wide " : "");
+ } else if (errno == EMFILE) {
+ error("Too many events are opened.\n"
+ "\t Try again after reducing the number of events,\n"
+ "\t tasks and/or cpus.");
} else {
error("open_counter returned with %d (%s). "
"/bin/dmesg may provide additional information.\n",
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index e3c63aef8efc..d0d05943fade 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -923,7 +923,8 @@ try_again:
goto out_err;
} else if (err == EMFILE) {
ui__warning("Too many events are opened.\n"
- "Try again after reducing the number of events\n");
+ "Try again after reducing the number of events,\n"
+ "tasks and/or cpus.\n");
goto out_err;
}
--
1.7.9
Ping. :)
2012-02-20 10:47 AM, Namhyung Kim wrote:
> On old kernels that don't support sample_id_all feature,
> perf_evlist__id2evsel() returns NULL for non-sampling events.
> This breaks perf top when multiple events are given on command
> line. Fix it by using first evsel in the evlist. This will also
> prevent getting the same (potential) problem in such new tool/
> old kernel combo.
>
> Suggested-by: Arnaldo Carvalho de Melo<[email protected]>
> Signed-off-by: Namhyung Kim<[email protected]>
> ---
> tools/perf/util/evlist.c | 4 ++++
> 1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index 5c61dc57d7c7..f8da9fada002 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -349,6 +349,10 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
> hlist_for_each_entry(sid, pos, head, node)
> if (sid->id == id)
> return sid->evsel;
> +
> + if (!perf_evlist__sample_id_all(evlist))
> + return list_entry(evlist->entries.next, struct perf_evsel, node);
> +
> return NULL;
> }
>