Skip to content

Commit

Permalink
perf tools: Prefer to use a cpu-wide event for probing CLOEXEC
Browse files Browse the repository at this point in the history
When doing a system-wide trace with Intel PT, the jump label set up as a
result of probing CLOEXEC gets reset while the trace is running.  That
causes an Intel PT decoding error because the object code (obtained from
/proc/kcore) does not match the running code at that point.  While we
can't expect there never to be jump label changes, we can avoid cases
that the perf tool itself creates.

The problem is avoided by first trying a cpu-wide event (pid = -1) for
probing the PERF_FLAG_FD_CLOEXEC flag and falling back to an event for
the current process (pid = 0).

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 46ec69a commit f6edb53
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions tools/perf/util/cloexec.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <sched.h>
#include "util.h"
#include "../perf.h"
#include "cloexec.h"
Expand All @@ -15,10 +16,23 @@ static int perf_flag_probe(void)
};
int fd;
int err;
int cpu;
pid_t pid = -1;

/* check cloexec flag */
fd = sys_perf_event_open(&attr, 0, -1, -1,
PERF_FLAG_FD_CLOEXEC);
cpu = sched_getcpu();
if (cpu < 0)
cpu = 0;

while (1) {
/* check cloexec flag */
fd = sys_perf_event_open(&attr, pid, cpu, -1,
PERF_FLAG_FD_CLOEXEC);
if (fd < 0 && pid == -1 && errno == EACCES) {
pid = 0;
continue;
}
break;
}
err = errno;

if (fd >= 0) {
Expand All @@ -31,7 +45,7 @@ static int perf_flag_probe(void)
err, strerror(err));

/* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */
fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
fd = sys_perf_event_open(&attr, pid, cpu, -1, 0);
err = errno;

if (WARN_ONCE(fd < 0 && err != EBUSY,
Expand Down

0 comments on commit f6edb53

Please sign in to comment.