brintos

brintos / linux-shallow public Read only

0
0
Text · 1.8 KiB · 8830604 Raw
93 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <errno.h>3#include <sched.h>4#include "util.h" // for sched_getcpu()5#include "../perf-sys.h"6#include "cloexec.h"7#include "event.h"8#include "asm/bug.h"9#include "debug.h"10#include <unistd.h>11#include <sys/syscall.h>12#include <linux/string.h>13 14static unsigned long flag = PERF_FLAG_FD_CLOEXEC;15 16static int perf_flag_probe(void)17{18	/* use 'safest' configuration as used in evsel__fallback() */19	struct perf_event_attr attr = {20		.type = PERF_TYPE_SOFTWARE,21		.config = PERF_COUNT_SW_CPU_CLOCK,22		.exclude_kernel = 1,23	};24	int fd;25	int err;26	int cpu;27	pid_t pid = -1;28	char sbuf[STRERR_BUFSIZE];29 30	cpu = sched_getcpu();31	if (cpu < 0)32		cpu = 0;33 34	/*35	 * Using -1 for the pid is a workaround to avoid gratuitous jump label36	 * changes.37	 */38	while (1) {39		/* check cloexec flag */40		fd = sys_perf_event_open(&attr, pid, cpu, -1,41					 PERF_FLAG_FD_CLOEXEC);42		if (fd < 0 && pid == -1 && errno == EACCES) {43			pid = 0;44			continue;45		}46		break;47	}48	err = errno;49 50	if (fd >= 0) {51		close(fd);52		return 1;53	}54 55	WARN_ONCE(err != EINVAL && err != EBUSY && err != EACCES,56		  "perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n",57		  err, str_error_r(err, sbuf, sizeof(sbuf)));58 59	/* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */60	while (1) {61		fd = sys_perf_event_open(&attr, pid, cpu, -1, 0);62		if (fd < 0 && pid == -1 && errno == EACCES) {63			pid = 0;64			continue;65		}66		break;67	}68	err = errno;69 70	if (fd >= 0)71		close(fd);72 73	if (WARN_ONCE(fd < 0 && err != EBUSY && err != EACCES,74		      "perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n",75		      err, str_error_r(err, sbuf, sizeof(sbuf))))76		return -1;77 78	return 0;79}80 81unsigned long perf_event_open_cloexec_flag(void)82{83	static bool probed;84 85	if (!probed) {86		if (perf_flag_probe() <= 0)87			flag = 0;88		probed = true;89	}90 91	return flag;92}93