xref: /linux/tools/perf/util/cloexec.c (revision e1e455f4f4d35850c30235747620d0d078fe9f64)
1f6edb53cSAdrian Hunter #include <sched.h>
257480d2cSYann Droneaud #include "util.h"
357480d2cSYann Droneaud #include "../perf.h"
457480d2cSYann Droneaud #include "cloexec.h"
557480d2cSYann Droneaud #include "asm/bug.h"
66e81c74cSMasami Hiramatsu #include "debug.h"
757480d2cSYann Droneaud 
857480d2cSYann Droneaud static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
957480d2cSYann Droneaud 
10*e1e455f4SVinson Lee int __weak sched_getcpu(void)
11*e1e455f4SVinson Lee {
12*e1e455f4SVinson Lee 	errno = ENOSYS;
13*e1e455f4SVinson Lee 	return -1;
14*e1e455f4SVinson Lee }
15*e1e455f4SVinson Lee 
1657480d2cSYann Droneaud static int perf_flag_probe(void)
1757480d2cSYann Droneaud {
1857480d2cSYann Droneaud 	/* use 'safest' configuration as used in perf_evsel__fallback() */
1957480d2cSYann Droneaud 	struct perf_event_attr attr = {
20038fa0b9SJiri Olsa 		.type = PERF_TYPE_SOFTWARE,
2157480d2cSYann Droneaud 		.config = PERF_COUNT_SW_CPU_CLOCK,
22a5b0153cSAdrian Hunter 		.exclude_kernel = 1,
2357480d2cSYann Droneaud 	};
2457480d2cSYann Droneaud 	int fd;
2557480d2cSYann Droneaud 	int err;
26f6edb53cSAdrian Hunter 	int cpu;
27f6edb53cSAdrian Hunter 	pid_t pid = -1;
286e81c74cSMasami Hiramatsu 	char sbuf[STRERR_BUFSIZE];
2957480d2cSYann Droneaud 
30f6edb53cSAdrian Hunter 	cpu = sched_getcpu();
31f6edb53cSAdrian Hunter 	if (cpu < 0)
32f6edb53cSAdrian Hunter 		cpu = 0;
33f6edb53cSAdrian Hunter 
3448536c91SAdrian Hunter 	/*
3548536c91SAdrian Hunter 	 * Using -1 for the pid is a workaround to avoid gratuitous jump label
3648536c91SAdrian Hunter 	 * changes.
3748536c91SAdrian Hunter 	 */
38f6edb53cSAdrian Hunter 	while (1) {
3957480d2cSYann Droneaud 		/* check cloexec flag */
40f6edb53cSAdrian Hunter 		fd = sys_perf_event_open(&attr, pid, cpu, -1,
4157480d2cSYann Droneaud 					 PERF_FLAG_FD_CLOEXEC);
42f6edb53cSAdrian Hunter 		if (fd < 0 && pid == -1 && errno == EACCES) {
43f6edb53cSAdrian Hunter 			pid = 0;
44f6edb53cSAdrian Hunter 			continue;
45f6edb53cSAdrian Hunter 		}
46f6edb53cSAdrian Hunter 		break;
47f6edb53cSAdrian Hunter 	}
4857480d2cSYann Droneaud 	err = errno;
4957480d2cSYann Droneaud 
5057480d2cSYann Droneaud 	if (fd >= 0) {
5157480d2cSYann Droneaud 		close(fd);
5257480d2cSYann Droneaud 		return 1;
5357480d2cSYann Droneaud 	}
5457480d2cSYann Droneaud 
5563914acaSJiri Olsa 	WARN_ONCE(err != EINVAL && err != EBUSY,
5657480d2cSYann Droneaud 		  "perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n",
576e81c74cSMasami Hiramatsu 		  err, strerror_r(err, sbuf, sizeof(sbuf)));
5857480d2cSYann Droneaud 
5957480d2cSYann Droneaud 	/* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */
6048536c91SAdrian Hunter 	while (1) {
61f6edb53cSAdrian Hunter 		fd = sys_perf_event_open(&attr, pid, cpu, -1, 0);
6248536c91SAdrian Hunter 		if (fd < 0 && pid == -1 && errno == EACCES) {
6348536c91SAdrian Hunter 			pid = 0;
6448536c91SAdrian Hunter 			continue;
6548536c91SAdrian Hunter 		}
6648536c91SAdrian Hunter 		break;
6748536c91SAdrian Hunter 	}
6857480d2cSYann Droneaud 	err = errno;
6957480d2cSYann Droneaud 
7048536c91SAdrian Hunter 	if (fd >= 0)
7148536c91SAdrian Hunter 		close(fd);
7248536c91SAdrian Hunter 
7363914acaSJiri Olsa 	if (WARN_ONCE(fd < 0 && err != EBUSY,
7457480d2cSYann Droneaud 		      "perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n",
756e81c74cSMasami Hiramatsu 		      err, strerror_r(err, sbuf, sizeof(sbuf))))
7657480d2cSYann Droneaud 		return -1;
7757480d2cSYann Droneaud 
7857480d2cSYann Droneaud 	return 0;
7957480d2cSYann Droneaud }
8057480d2cSYann Droneaud 
8157480d2cSYann Droneaud unsigned long perf_event_open_cloexec_flag(void)
8257480d2cSYann Droneaud {
8357480d2cSYann Droneaud 	static bool probed;
8457480d2cSYann Droneaud 
8557480d2cSYann Droneaud 	if (!probed) {
8657480d2cSYann Droneaud 		if (perf_flag_probe() <= 0)
8757480d2cSYann Droneaud 			flag = 0;
8857480d2cSYann Droneaud 		probed = true;
8957480d2cSYann Droneaud 	}
9057480d2cSYann Droneaud 
9157480d2cSYann Droneaud 	return flag;
9257480d2cSYann Droneaud }
93