perf tools: Show better error message in case we fail to open counters due to EBUSY error
Jiri Olsa
reviewerPATCH 1/1 perf tools: Show better error message in case we fail to open counters due to EBUSY error
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.
--- tools/perf/util/cloexec.c | 4 ++-- tools/perf/util/evsel.c | 6 ++++++ tools/perf/util/util.c | 36 ++++++++++++++++++++++++++++++++++++ tools/perf/util/util.h | 1 + 4 files changed, 45 insertions(+), 2 deletions(-)
tools/perf/util/cloexec.c +2 -2
@@ -25,7 +25,7 @@ static int perf_flag_probe(void)return 1 ; } -WARN_ONCE (err !=EINVAL , +WARN_ONCE (err !=EINVAL && err !=EBUSY ,"perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n" , err,strerror (err));
@@ -33,7 +33,7 @@ static int perf_flag_probe(void) fd =sys_perf_event_open (&attr,0 ,-1 ,-1 ,0 ); err = errno; -if (WARN_ONCE (fd <0 , +if (WARN_ONCE (fd <0 && err !=EBUSY ,"perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n" , err,strerror (err)))return -1 ;
tools/perf/util/evsel.c +6 -0
@@ -2036,6 +2036,12 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, "No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it.");#endif break ; +case EBUSY : +if (find_process ("oprofiled" )) +return scnprintf (msg, size, +"The PMU counters are busy/taken by another profiler.\n" +"We found oprofile daemon running, please stop it and try again." ); +break ;default :break ; }
tools/perf/util/util.c +36 -0
@@ -536,3 +536,39 @@ void mem_bswap_64(void *src, int byte_size) ++m; } } + +bool find_process (const char *name) +{ +size_t len =strlen (name); +DIR *dir; +struct dirent *d; +int ret =-1 ; + + dir =opendir (procfs__mountpoint ()); +if (!dir) +return -1 ; + +/* Walk through the directory. */ +while (ret && (d =readdir (dir)) !=NULL ) { +char path[PATH_MAX ]; +char *data; +size_t size; + +if ((d->d_type !=DT_DIR ) || + !strcmp ("." , d->d_name) || + !strcmp (".." , d->d_name)) +continue ; + +scnprintf (path,sizeof (path),"%s/%s/comm" , +procfs__mountpoint (), d->d_name); + +if (filename__read_str (path, &data, &size)) +continue ; + + ret =strncmp (name, data, len); +free (data); + } + +closedir (dir); +return ret ? false : true; +}
tools/perf/util/util.h +1 -0
@@ -330,4 +330,5 @@ void mem_bswap_64(void *src, int byte_size);void mem_bswap_32 (void *src,int byte_size);const char *get_filename_for_perf_kvm (void ); +bool find_process (const char *name);#endif /* GIT_COMPAT_UTIL_H */
Signature · 1 line
1.8.3.1
Hi Jiri,
Quoted 61 lines · Jiri Olsa
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_CLOEXECdetection 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.Cc Adrian Hunter <[email protected]>Cc Arnaldo Carvalho de Melo <[email protected]>Cc David Ahern <[email protected]>Cc Frederic Weisbecker <[email protected]>Cc Namhyung Kim <[email protected]>Cc Paul Mackerras <[email protected]>Cc Peter Zijlstra <[email protected]>Cc Stephane Eranian <[email protected]>Cc William Cohen <[email protected]>Cc Yann Droneaud <[email protected]>Signed-off-by Jiri Olsa <[email protected]>--- tools/perf/util/cloexec.c | 4 ++-- tools/perf/util/evsel.c | 6 ++++++ tools/perf/util/util.c | 36 ++++++++++++++++++++++++++++++++++++ tools/perf/util/util.h | 1 + 4 files changed, 45 insertions(+), 2 deletions(-)tools/perf/util/cloexec.c +1
-1@@ -25,7 +25,7 @@ static int perf_flag_probe(void)return 1 ; } -WARN_ONCE (err !=EINVAL , +WARN_ONCE (err !=EINVAL && err !=EBUSY ,"perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n" , err,strerror (err));
tools/perf/util/cloexec.c static int perf_flag_probe(void) · line 39
Quoted 8 lines
tools/perf/util/cloexec.c +1
-1@@ -33,7 +33,7 @@ static int perf_flag_probe(void) fd =sys_perf_event_open (&attr,0 ,-1 ,-1 ,0 ); err = errno; -if (WARN_ONCE (fd <0 , +if (WARN_ONCE (fd <0 && err !=EBUSY ,"perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n" , err,strerror (err)))return -1 ;
It's definitely possible to shortcut the function if EBUSY is returned by first call to perf_event_open().
tools/perf/util/cloexec.c +3 -0
@@ -25,6 +25,9 @@ static int perf_flag_probe(void)return 1 ; } +if (err ==EBUSY ) +return -1 ; +WARN_ONCE (err !=EINVAL ,"perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n" , err,strerror (err));
BTW, I'm going to submit a patch to make the function report such warning only once.
Regards.
Signature · 2 lines
Yann Droneaud OPTEYA
PATCH 1/1 perf tools: Fix PERF_FLAG_FD_CLOEXEC flag probing event type open counters due to EBUSY error
Quoted 1 line · Yann Droneaud
Hi Jiri,
SNIP
Quoted 16 lines
Review
Quoted 7 lines
(quoted diff) +1
-1err = errno; - if (WARN_ONCE(fd < 0, + if (WARN_ONCE(fd < 0 && err != EBUSY, "perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n", err, strerror(err))) return -1;It's definitely possible to shortcut the function if EBUSY is returned by first call to
perf_event_open().tools/perf/util/cloexec.c +0
-0
tools/perf/util/cloexec.c static int perf_flag_probe(void) · line 33
Quoted 9 lines
tools/perf/util/cloexec.c +3
-0@@ -25,6 +25,9 @@ static int perf_flag_probe(void)return 1 ; } +if (err ==EBUSY ) +return -1 ; +WARN_ONCE (err !=EINVAL ,"perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n" , err,strerror (err));
heh, I haven't realized that your probing event was PERF_COUNT_SW_CPU_CLOCK, which could never be busy and found following bug ;-)
jirka
---
We were using PERF_COUNT_SW_CPU_CLOCK as an probing event type. Using expected PERF_TYPE_SOFTWARE type instead.
--- tools/perf/util/cloexec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/cloexec.c +1 -1
@@ -9,7 +9,7 @@ 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 , + .type =PERF_TYPE_SOFTWARE , .config =PERF_COUNT_SW_CPU_CLOCK , };int fd;
Signature · 1 line
1.8.3.1
Re: [PATCH] perf tools: Fix PERF_FLAG_FD_CLOEXEC flag probing event type open counters due to EBUSY error
Hi,
Quoted 33 lines · Jiri Olsa
On Sat, Aug 02, 2014 at 07:58:25PM +0200, Yann Droneaud wrote:
heh, I haven't realized that your probing event was
PERF_COUNT_SW_CPU_CLOCK, which could never be busy and found following bug ;-)jirka
---
We were usingPERF_COUNT_SW_CPU_CLOCKas an probing event type. Using expectedPERF_TYPE_SOFTWAREtype instead.Cc Adrian Hunter <[email protected]>Cc Arnaldo Carvalho de Melo <[email protected]>Cc David Ahern <[email protected]>Cc Frederic Weisbecker <[email protected]>Cc Namhyung Kim <[email protected]>Cc Paul Mackerras <[email protected]>Cc Peter Zijlstra <[email protected]>Cc Stephane Eranian <[email protected]>Cc William Cohen <[email protected]>Cc Yann Droneaud <[email protected]>Signed-off-by Jiri Olsa <[email protected]>--- tools/perf/util/cloexec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)tools/perf/util/cloexec.c +0
-0
tools/perf/util/cloexec.c static int perf_flag_probe(void) · line 13
Quoted 6 lines
tools/perf/util/cloexec.c +1
-1@@ -9,7 +9,7 @@ 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 , + .type =PERF_TYPE_SOFTWARE , .config =PERF_COUNT_SW_CPU_CLOCK ,
erf ... I was even not able to copy paste correctly the configuration used in perf_evsel__fallback(), my bad.
Thanks for the fix.
Regards.
Signature · 2 lines
Yann Droneaud OPTEYA
tip-bot for Jiri Olsa
merge bot[tip:perf/core] perf tools: Fix PERF_FLAG_FD_CLOEXEC flag probing event type open counters due to EBUSY error
In reply to Jiri Olsaperf tools: Fix PERF_FLAG_FD_CLOEXEC flag probing event type open counters due to EBUSY error
Commit-ID: 038fa0b9739d7f375f3f61a2ce4f78ad44329f66 Gitweb: http://git.kernel.org/tip/038fa0b9739d7f375f3f61a2ce4f78ad44329f66 Author: Jiri Olsa <[email protected]> AuthorDate: Sun, 3 Aug 2014 14:10:36 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Tue, 12 Aug 2014 12:03:08 -0300
perf tools: Fix PERF_FLAG_FD_CLOEXEC flag probing event type open counters due to EBUSY error
We were using PERF_COUNT_SW_CPU_CLOCK as an probing event type. Using expected PERF_TYPE_SOFTWARE type instead.
--- tools/perf/util/cloexec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/cloexec.c +1 -1
@@ -9,7 +9,7 @@ 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 , + .type =PERF_TYPE_SOFTWARE , .config =PERF_COUNT_SW_CPU_CLOCK , };int fd;
PATCH 1/1 perf tools: report PERF_FLAG_FD_CLOEXEC probing error once
In reply to Jiri OlsaIn case of failure, unrelated to PERF_FLAG_FD_CLOEXEC, perf_flag_probe() reports the error twice. For example:
$ 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.
This patch changes the function to only report a second error message when the two calls to perf_even_open(2) fail with different error codes.
--- tools/perf/util/cloexec.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
tools/perf/util/cloexec.c +13 -11
@@ -13,34 +13,36 @@ static int perf_flag_probe(void) .config = PERF_COUNT_SW_CPU_CLOCK, };int fd; -int err; +int err0, err1;/* check cloexec flag */ fd =sys_perf_event_open (&attr,0 ,-1 ,-1 ,PERF_FLAG_FD_CLOEXEC ); - err = errno; + err0 = errno;if (fd >=0 ) {close (fd);return 1 ; } -WARN_ONCE (err !=EINVAL , +WARN_ONCE (err0 !=EINVAL ,"perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n" , - err,strerror (err)); + err0,strerror (err0));/* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */ fd =sys_perf_event_open (&attr,0 ,-1 ,-1 ,0 ); - err = errno; + err1 = errno; -if (WARN_ONCE (fd <0 , -"perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n" , - err,strerror (err))) -return -1 ; +if (fd >=0 ) { +close (fd); +return 0 ; + } -close (fd); +WARN_ONCE (err0 != err1, +"perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n" , + err1,strerror (err1)); -return 0 ; +return -1 ; }unsigned long perf_event_open_cloexec_flag (void )
Signature · 1 line
1.9.3
Re: [PATCH] perf tools: report PERF_FLAG_FD_CLOEXEC probing error once
Quoted 7 lines · Yann Droneaud
In case of failure, unrelated to
PERF_FLAG_FD_CLOEXEC,perf_flag_probe()reports the error twice. For example:$ 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)
seems ok,
but since your patch is not based on my other patch, please provide the changelog perf out without it
---
Quoted 2 lines
The PMU counters are busy/taken by another profiler. We found oprofile daemon running, please stop it and try again.
---
also, please provide both before and after outputs I'll queue it up with those other 2 patches
thanks,
jirka
tip-bot for Jiri Olsa
merge botperf tools: Show better error message in case we fail to open counters due to EBUSY error
Commit-ID: 63914aca8f7e7a75d0ee027af7b1755c69cc1e2c Gitweb: http://git.kernel.org/tip/63914aca8f7e7a75d0ee027af7b1755c69cc1e2c Author: Jiri Olsa <[email protected]> AuthorDate: Fri, 1 Aug 2014 17:46:54 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Tue, 12 Aug 2014 12:03:02 -0300
perf tools: Show better error message in case we fail to open counters due to EBUSY error
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.
--- tools/perf/util/cloexec.c | 4 ++-- tools/perf/util/evsel.c | 6 ++++++ tools/perf/util/util.c | 36 ++++++++++++++++++++++++++++++++++++ tools/perf/util/util.h | 1 + 4 files changed, 45 insertions(+), 2 deletions(-)
tools/perf/util/cloexec.c +2 -2
@@ -25,7 +25,7 @@ static int perf_flag_probe(void)return 1 ; } -WARN_ONCE (err !=EINVAL , +WARN_ONCE (err !=EINVAL && err !=EBUSY ,"perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n" , err,strerror (err));
@@ -33,7 +33,7 @@ static int perf_flag_probe(void) fd =sys_perf_event_open (&attr,0 ,-1 ,-1 ,0 ); err = errno; -if (WARN_ONCE (fd <0 , +if (WARN_ONCE (fd <0 && err !=EBUSY ,"perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n" , err,strerror (err)))return -1 ;
tools/perf/util/evsel.c +6 -0
@@ -2039,6 +2039,12 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, "No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it.");#endif break ; +case EBUSY : +if (find_process ("oprofiled" )) +return scnprintf (msg, size, +"The PMU counters are busy/taken by another profiler.\n" +"We found oprofile daemon running, please stop it and try again." ); +break ;default :break ; }
tools/perf/util/util.c +36 -0
@@ -536,3 +536,39 @@ void mem_bswap_64(void *src, int byte_size) ++m; } } + +bool find_process (const char *name) +{ +size_t len =strlen (name); +DIR *dir; +struct dirent *d; +int ret =-1 ; + + dir =opendir (procfs__mountpoint ()); +if (!dir) +return -1 ; + +/* Walk through the directory. */ +while (ret && (d =readdir (dir)) !=NULL ) { +char path[PATH_MAX ]; +char *data; +size_t size; + +if ((d->d_type !=DT_DIR ) || + !strcmp ("." , d->d_name) || + !strcmp (".." , d->d_name)) +continue ; + +scnprintf (path,sizeof (path),"%s/%s/comm" , +procfs__mountpoint (), d->d_name); + +if (filename__read_str (path, &data, &size)) +continue ; + + ret =strncmp (name, data, len); +free (data); + } + +closedir (dir); +return ret ? false : true; +}
tools/perf/util/util.h +1 -0
@@ -346,4 +346,5 @@ void mem_bswap_64(void *src, int byte_size);void mem_bswap_32 (void *src,int byte_size);const char *get_filename_for_perf_kvm (void ); +bool find_process (const char *name);#endif /* GIT_COMPAT_UTIL_H */