1 #include <stdint.h>
2 #include <fcntl.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <sys/sysinfo.h>
8
9 #include "igt_perf.h"
10
i915_type_id(void)11 uint64_t i915_type_id(void)
12 {
13 char buf[64];
14 ssize_t ret;
15 int fd;
16
17 fd = open("/sys/bus/event_source/devices/i915/type", O_RDONLY);
18 if (fd < 0)
19 return 0;
20
21 ret = read(fd, buf, sizeof(buf) - 1);
22 close(fd);
23 if (ret < 1)
24 return 0;
25
26 buf[ret] = '\0';
27
28 return strtoull(buf, NULL, 0);
29 }
30
31 static int
_perf_open(uint64_t type,uint64_t config,int group,uint64_t format)32 _perf_open(uint64_t type, uint64_t config, int group, uint64_t format)
33 {
34 struct perf_event_attr attr = { };
35 int nr_cpus = get_nprocs_conf();
36 int cpu = 0, ret;
37
38 attr.type = type;
39 if (attr.type == 0)
40 return -ENOENT;
41
42 if (group >= 0)
43 format &= ~PERF_FORMAT_GROUP;
44
45 attr.read_format = format;
46 attr.config = config;
47
48 do {
49 ret = perf_event_open(&attr, -1, cpu++, group, 0);
50 } while ((ret < 0 && errno == EINVAL) && (cpu < nr_cpus));
51
52 return ret;
53 }
54
perf_i915_open(uint64_t config)55 int perf_i915_open(uint64_t config)
56 {
57 return _perf_open(i915_type_id(), config, -1,
58 PERF_FORMAT_TOTAL_TIME_ENABLED);
59 }
60
perf_i915_open_group(uint64_t config,int group)61 int perf_i915_open_group(uint64_t config, int group)
62 {
63 return _perf_open(i915_type_id(), config, group,
64 PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP);
65 }
66
igt_perf_open(uint64_t type,uint64_t config)67 int igt_perf_open(uint64_t type, uint64_t config)
68 {
69 return _perf_open(type, config, -1,
70 PERF_FORMAT_TOTAL_TIME_ENABLED);
71 }
72
igt_perf_open_group(uint64_t type,uint64_t config,int group)73 int igt_perf_open_group(uint64_t type, uint64_t config, int group)
74 {
75 return _perf_open(type, config, group,
76 PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_GROUP);
77 }
78