forked from Minki/linux
63914aca8f
Showing better error message in case we fail to open counters due to the EBUSY error. If we detect oprofile daemon process running, we now display following message for EBUSY error: $ perf record ls Error: The PMU counters are busy/taken by another profiler. We found oprofile daemon running, please stop it and try again. In case oprofiled was not detected the current error message stays: $ perf record ls Error: The sys_perf_event_open() syscall returned with 16 (Device or resource busy) for event (cycles). /bin/dmesg may provide additional information. No CONFIG_PERF_EVENTS=y kernel support configured? Also changing PERF_FLAG_FD_CLOEXEC detection code not to display error in case of EBUSY error, as it currently does: $ perf record ls Error: perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error 16 (Device or resource busy) perf_event_open(..., 0) failed unexpectedly with error 16 (Device or resource busy) The PMU counters are busy/taken by another profiler. We found oprofile daemon running, please stop it and try again. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.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> Cc: William Cohen <wcohen@redhat.com> Cc: Yann Droneaud <ydroneaud@opteya.com> Link: http://lkml.kernel.org/r/1406908014-8312-1-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
58 lines
1.1 KiB
C
58 lines
1.1 KiB
C
#include "util.h"
|
|
#include "../perf.h"
|
|
#include "cloexec.h"
|
|
#include "asm/bug.h"
|
|
|
|
static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
|
|
|
|
static int perf_flag_probe(void)
|
|
{
|
|
/* use 'safest' configuration as used in perf_evsel__fallback() */
|
|
struct perf_event_attr attr = {
|
|
.type = PERF_COUNT_SW_CPU_CLOCK,
|
|
.config = PERF_COUNT_SW_CPU_CLOCK,
|
|
};
|
|
int fd;
|
|
int err;
|
|
|
|
/* check cloexec flag */
|
|
fd = sys_perf_event_open(&attr, 0, -1, -1,
|
|
PERF_FLAG_FD_CLOEXEC);
|
|
err = errno;
|
|
|
|
if (fd >= 0) {
|
|
close(fd);
|
|
return 1;
|
|
}
|
|
|
|
WARN_ONCE(err != EINVAL && err != EBUSY,
|
|
"perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n",
|
|
err, strerror(err));
|
|
|
|
/* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */
|
|
fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
|
|
err = errno;
|
|
|
|
if (WARN_ONCE(fd < 0 && err != EBUSY,
|
|
"perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n",
|
|
err, strerror(err)))
|
|
return -1;
|
|
|
|
close(fd);
|
|
|
|
return 0;
|
|
}
|
|
|
|
unsigned long perf_event_open_cloexec_flag(void)
|
|
{
|
|
static bool probed;
|
|
|
|
if (!probed) {
|
|
if (perf_flag_probe() <= 0)
|
|
flag = 0;
|
|
probed = true;
|
|
}
|
|
|
|
return flag;
|
|
}
|