15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "evsel.h"
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tests.h"
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "thread_map.h"
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "cpumap.h"
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "debug.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int test__open_syscall_event_on_all_cpus(void)
8eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{
9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	int err = -1, fd, cpu;
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	struct cpu_map *cpus;
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	struct perf_evsel *evsel;
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	unsigned int nr_open_calls = 111, i;
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)	cpu_set_t cpu_set;
14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX);
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)	if (threads == NULL) {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pr_debug("thread_map__new\n");
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		return -1;
1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	}
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	cpus = cpu_map__new(NULL);
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	if (cpus == NULL) {
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		pr_debug("cpu_map__new\n");
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto out_thread_map_delete;
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	}
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)	CPU_ZERO(&cpu_set);
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (evsel == NULL) {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		goto out_thread_map_delete;
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)	}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	if (perf_evsel__open(evsel, cpus, threads) < 0) {
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		pr_debug("failed to open counter: %s, "
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch			 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch			 strerror(errno));
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		goto out_evsel_delete;
40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	}
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	for (cpu = 0; cpu < cpus->nr; ++cpu) {
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		unsigned int ncalls = nr_open_calls + cpu;
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		/*
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * XXX eventually lift this restriction in a way that
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * keeps perf building on older glibc installations
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		 * without CPU_ALLOC. 1024 cpus in 2010 still seems
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * a reasonable upper limit tho :-)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (cpus->map[cpu] >= CPU_SETSIZE) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			pr_debug("Ignoring CPU %d\n", cpus->map[cpu]);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			continue;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		CPU_SET(cpus->map[cpu], &cpu_set);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			pr_debug("sched_setaffinity() failed on CPU %d: %s ",
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)				 cpus->map[cpu],
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 strerror(errno));
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch			goto out_close_fd;
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		}
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)		for (i = 0; i < ncalls; ++i) {
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch			fd = open("/etc/passwd", O_RDONLY);
64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch			close(fd);
65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		}
66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		CPU_CLR(cpus->map[cpu], &cpu_set);
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	}
68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	/*
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * Here we need to explicitely preallocate the counts, as if
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * we use the auto allocation it will allocate just for 1 cpu,
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 * as we start by cpu 0.
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	 */
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) {
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)		goto out_close_fd;
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	}
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)	err = 0;
8046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)	for (cpu = 0; cpu < cpus->nr; ++cpu) {
8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		unsigned int expected;
8346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		if (cpus->map[cpu] >= CPU_SETSIZE)
8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)			continue;
8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)		if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) {
8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)			pr_debug("perf_evsel__read_on_cpu\n");
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch			err = -1;
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch			break;
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		}
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		expected = nr_open_calls + cpu;
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		if (evsel->counts->cpu[cpu].val != expected) {
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch			pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch				 expected, cpus->map[cpu], evsel->counts->cpu[cpu].val);
97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch			err = -1;
98eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch		}
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	}
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	perf_evsel__free_counts(evsel);
102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochout_close_fd:
103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	perf_evsel__close_fd(evsel, 1, threads->nr);
104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochout_evsel_delete:
105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	perf_evsel__delete(evsel);
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)out_thread_map_delete:
107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	thread_map__delete(threads);
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch	return err;
109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)