Commit f6edb53c authored by Adrian Hunter's avatar Adrian Hunter Committed by Arnaldo Carvalho de Melo

perf tools: Prefer to use a cpu-wide event for probing CLOEXEC

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: default avatarAdrian Hunter <adrian.hunter@intel.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@gmail.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/1407855871-15024-5-git-send-email-adrian.hunter@intel.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 46ec69ad
#include <sched.h>
#include "util.h" #include "util.h"
#include "../perf.h" #include "../perf.h"
#include "cloexec.h" #include "cloexec.h"
...@@ -15,10 +16,23 @@ static int perf_flag_probe(void) ...@@ -15,10 +16,23 @@ static int perf_flag_probe(void)
}; };
int fd; int fd;
int err; int err;
int cpu;
pid_t pid = -1;
cpu = sched_getcpu();
if (cpu < 0)
cpu = 0;
while (1) {
/* check cloexec flag */ /* check cloexec flag */
fd = sys_perf_event_open(&attr, 0, -1, -1, fd = sys_perf_event_open(&attr, pid, cpu, -1,
PERF_FLAG_FD_CLOEXEC); PERF_FLAG_FD_CLOEXEC);
if (fd < 0 && pid == -1 && errno == EACCES) {
pid = 0;
continue;
}
break;
}
err = errno; err = errno;
if (fd >= 0) { if (fd >= 0) {
...@@ -31,7 +45,7 @@ static int perf_flag_probe(void) ...@@ -31,7 +45,7 @@ static int perf_flag_probe(void)
err, strerror(err)); err, strerror(err));
/* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */ /* 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; err = errno;
if (WARN_ONCE(fd < 0 && err != EBUSY, if (WARN_ONCE(fd < 0 && err != EBUSY,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment