1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "evsel.h"
2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "tests.h"
3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "thread_map.h"
4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "cpumap.h"
5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "debug.h"
6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint test__open_syscall_event_on_all_cpus(void)
8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int err = -1, fd, cpu;
10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cpu_map *cpus;
11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evsel *evsel;
12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned int nr_open_calls = 111, i;
13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	cpu_set_t cpu_set;
14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX);
15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (threads == NULL) {
17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pr_debug("thread_map__new\n");
18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	cpus = cpu_map__new(NULL);
22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (cpus == NULL) {
23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pr_debug("cpu_map__new\n");
24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_thread_map_delete;
25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	CPU_ZERO(&cpu_set);
28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0);
30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (evsel == NULL) {
31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_thread_map_delete;
33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (perf_evsel__open(evsel, cpus, threads) < 0) {
36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pr_debug("failed to open counter: %s, "
37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 strerror(errno));
39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_evsel_delete;
40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (cpu = 0; cpu < cpus->nr; ++cpu) {
43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		unsigned int ncalls = nr_open_calls + cpu;
44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		/*
45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * XXX eventually lift this restriction in a way that
46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * keeps perf building on older glibc installations
47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * without CPU_ALLOC. 1024 cpus in 2010 still seems
48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 * a reasonable upper limit tho :-)
49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 */
50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (cpus->map[cpu] >= CPU_SETSIZE) {
51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_debug("Ignoring CPU %d\n", cpus->map[cpu]);
52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			continue;
53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		CPU_SET(cpus->map[cpu], &cpu_set);
56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_debug("sched_setaffinity() failed on CPU %d: %s ",
58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 cpus->map[cpu],
59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 strerror(errno));
60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto out_close_fd;
61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		for (i = 0; i < ncalls; ++i) {
63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			fd = open("/etc/passwd", O_RDONLY);
64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			close(fd);
65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		CPU_CLR(cpus->map[cpu], &cpu_set);
67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * Here we need to explicitely preallocate the counts, as if
71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * we use the auto allocation it will allocate just for 1 cpu,
72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * as we start by cpu 0.
73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) {
75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_close_fd;
77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	err = 0;
80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (cpu = 0; cpu < cpus->nr; ++cpu) {
82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		unsigned int expected;
83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (cpus->map[cpu] >= CPU_SETSIZE)
85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			continue;
86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) {
88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_debug("perf_evsel__read_on_cpu\n");
89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			err = -1;
90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		expected = nr_open_calls + cpu;
94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (evsel->counts->cpu[cpu].val != expected) {
95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 expected, cpus->map[cpu], evsel->counts->cpu[cpu].val);
97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			err = -1;
98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perf_evsel__free_counts(evsel);
102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_close_fd:
103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perf_evsel__close_fd(evsel, 1, threads->nr);
104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_evsel_delete:
105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perf_evsel__delete(evsel);
106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_thread_map_delete:
107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	thread_map__delete(threads);
108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return err;
109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
110