blob: dede0c388ed4b24edc16d4c0936626bf61098bd5 [file] [log] [blame]
Yann Droneaud57480d22014-06-30 22:28:47 +02001#include "util.h"
2#include "../perf.h"
3#include "cloexec.h"
4#include "asm/bug.h"
5
6static unsigned long flag = PERF_FLAG_FD_CLOEXEC;
7
8static int perf_flag_probe(void)
9{
10 /* use 'safest' configuration as used in perf_evsel__fallback() */
11 struct perf_event_attr attr = {
12 .type = PERF_COUNT_SW_CPU_CLOCK,
13 .config = PERF_COUNT_SW_CPU_CLOCK,
14 };
15 int fd;
16 int err;
17
18 /* check cloexec flag */
Jiri Olsa8578b892014-07-28 15:58:47 +020019 fd = sys_perf_event_open(&attr, 0, -1, -1,
Yann Droneaud57480d22014-06-30 22:28:47 +020020 PERF_FLAG_FD_CLOEXEC);
21 err = errno;
22
23 if (fd >= 0) {
24 close(fd);
25 return 1;
26 }
27
Jiri Olsa63914ac2014-08-01 17:46:54 +020028 WARN_ONCE(err != EINVAL && err != EBUSY,
Yann Droneaud57480d22014-06-30 22:28:47 +020029 "perf_event_open(..., PERF_FLAG_FD_CLOEXEC) failed with unexpected error %d (%s)\n",
30 err, strerror(err));
31
32 /* not supported, confirm error related to PERF_FLAG_FD_CLOEXEC */
Jiri Olsa8578b892014-07-28 15:58:47 +020033 fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
Yann Droneaud57480d22014-06-30 22:28:47 +020034 err = errno;
35
Jiri Olsa63914ac2014-08-01 17:46:54 +020036 if (WARN_ONCE(fd < 0 && err != EBUSY,
Yann Droneaud57480d22014-06-30 22:28:47 +020037 "perf_event_open(..., 0) failed unexpectedly with error %d (%s)\n",
38 err, strerror(err)))
39 return -1;
40
41 close(fd);
42
43 return 0;
44}
45
46unsigned long perf_event_open_cloexec_flag(void)
47{
48 static bool probed;
49
50 if (!probed) {
51 if (perf_flag_probe() <= 0)
52 flag = 0;
53 probed = true;
54 }
55
56 return flag;
57}