Contributors: 12
Author |
Tokens |
Token Proportion |
Commits |
Commit Proportion |
Yann Droneaud |
139 |
40.17% |
1 |
3.45% |
Adrian Hunter |
109 |
31.50% |
4 |
13.79% |
Arnaldo Carvalho de Melo |
36 |
10.40% |
10 |
34.48% |
Jiri Olsa |
20 |
5.78% |
5 |
17.24% |
Peter Zijlstra |
14 |
4.05% |
1 |
3.45% |
Ingo Molnar |
8 |
2.31% |
2 |
6.90% |
Alexey Budankov |
8 |
2.31% |
1 |
3.45% |
Masami Hiramatsu |
6 |
1.73% |
1 |
3.45% |
Alexander Yarygin |
3 |
0.87% |
1 |
3.45% |
Robert Richter |
1 |
0.29% |
1 |
3.45% |
Ulrich Drepper |
1 |
0.29% |
1 |
3.45% |
Greg Kroah-Hartman |
1 |
0.29% |
1 |
3.45% |
Total |
346 |
|
29 |
|
// SPDX-License-Identifier: GPL-2.0
#include <errno.h>
#include <sched.h>
#include "util.h" // for sched_getcpu()
#include "../perf-sys.h"
#include "cloexec.h"
#include "event.h"
#include "asm/bug.h"
#include "debug.h"
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/string.h>
static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
static int perf_flag_probe(void)
{
/* use 'safest' configuration as used in evsel__fallback() */
struct perf_event_attr attr = {
.type = PERF_TYPE_SOFTWARE,
.config = PERF_COUNT_SW_CPU_CLOCK,
.exclude_kernel = 1,
};
int fd;
int err;
int cpu;
pid_t pid = -1;
char sbuf[STRERR_BUFSIZE];
cpu = sched_getcpu();
if (cpu < 0)
cpu = 0;
/*
* Using -1 for the pid is a workaround to avoid gratuitous jump label
* changes.
*/
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) {
close(fd);
return 1;
}
WARN_ONCE(err != EINVAL && err != EBUSY && err != EACCES,
"perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n",
err, str_error_r(err, sbuf, sizeof(sbuf)));
/* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */
while (1) {
fd = sys_perf_event_open(&attr, pid, cpu, -1, 0);
if (fd < 0 && pid == -1 && errno == EACCES) {
pid = 0;
continue;
}
break;
}
err = errno;
if (fd >= 0)
close(fd);
if (WARN_ONCE(fd < 0 && err != EBUSY && err != EACCES,
"perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n",
err, str_error_r(err, sbuf, sizeof(sbuf))))
return -1;
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;
}