Skip to content

Commit

Permalink
perf tools: Fix probing the kernel API with cpu-wide events
Browse files Browse the repository at this point in the history
Fall back to probing with the current pid if cpu-wide probing fails.
This primarily affects the setting of comm_exec flag when the user is
un-privileged and /proc/sys/kernel/perf_event_paranoid > 0.

The change to comm_exec can be observed by using -vv with perf record
and a kernel that supports comm_exec.

Signed-off-by: Adrian Hunter <[email protected]>
Acked-by: Jiri Olsa <[email protected]>
Cc: David Ahern <[email protected]>
Cc: Frederic Weisbecker <[email protected]>
Cc: Jiri Olsa <[email protected]>
Cc: Namhyung Kim <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Peter Zijlstra <[email protected]>
Cc: Stephane Eranian <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
ahunter6 authored and acmel committed Aug 13, 2014
1 parent c6fa356 commit 46ec69a
Showing 1 changed file with 27 additions and 9 deletions.
36 changes: 27 additions & 9 deletions tools/perf/util/record.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)
struct perf_evsel *evsel;
unsigned long flags = perf_event_open_cloexec_flag();
int err = -EAGAIN, fd;
static pid_t pid = -1;

evlist = perf_evlist__new();
if (!evlist)
Expand All @@ -24,14 +25,22 @@ static int perf_do_probe_api(setup_probe_fn_t fn, int cpu, const char *str)

evsel = perf_evlist__first(evlist);

fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, flags);
if (fd < 0)
goto out_delete;
while (1) {
fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags);
if (fd < 0) {
if (pid == -1 && errno == EACCES) {
pid = 0;
continue;
}
goto out_delete;
}
break;
}
close(fd);

fn(evsel);

fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1, flags);
fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1, flags);
if (fd < 0) {
if (errno == EINVAL)
err = -EINVAL;
Expand Down Expand Up @@ -201,6 +210,7 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
struct perf_evsel *evsel;
int err, fd, cpu;
bool ret = false;
pid_t pid = -1;

temp_evlist = perf_evlist__new();
if (!temp_evlist)
Expand All @@ -221,12 +231,20 @@ bool perf_evlist__can_select_event(struct perf_evlist *evlist, const char *str)
cpu = evlist->cpus->map[0];
}

fd = sys_perf_event_open(&evsel->attr, -1, cpu, -1,
perf_event_open_cloexec_flag());
if (fd >= 0) {
close(fd);
ret = true;
while (1) {
fd = sys_perf_event_open(&evsel->attr, pid, cpu, -1,
perf_event_open_cloexec_flag());
if (fd < 0) {
if (pid == -1 && errno == EACCES) {
pid = 0;
continue;
}
goto out_delete;
}
break;
}
close(fd);
ret = true;

out_delete:
perf_evlist__delete(temp_evlist);
Expand Down

0 comments on commit 46ec69a

Please sign in to comment.