// 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;
}
Messung V0.5 in Prozent C=97 H=92 G=94
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-07)
¤
*© Formatika GbR, Deutschland