/* * This test will generate random numbers of calls to some getpid syscalls, * then establish an mmap for a group of events that are created to monitor * the syscalls. * * It will receive the events, using mmap, use its PERF_SAMPLE_ID generated * sample.id field to map back to its respective perf_evsel instance. * * Then it checks if the number of syscalls reported as perf events by * the kernel corresponds to the number of syscalls made.
*/ staticint test__basic_mmap(struct test_suite *test __maybe_unused, int subtest __maybe_unused)
{ int err = TEST_FAIL; union perf_event *event; struct perf_thread_map *threads; struct perf_cpu_map *cpus; struct evlist *evlist;
cpu_set_t cpu_set; constchar *syscall_names[] = { "getsid", "getppid", "getpgid", };
pid_t (*syscalls[])(void) = { (void *)getsid, getppid, (void*)getpgid }; #define nsyscalls ARRAY_SIZE(syscall_names) unsignedint nr_events[nsyscalls],
expected_nr_events[nsyscalls], i, j; struct evsel *evsels[nsyscalls], *evsel; char sbuf[STRERR_BUFSIZE]; struct mmap *md;
len = read(rdpmc_fd, buf, sizeof(buf)); if (len != sizeof(buf))
pr_debug("%s read failed\n", __func__);
// Note, on Intel hybrid disabling on 1 PMU will implicitly disable on // all the core PMUs.
old_user_read = (buf[0] == '1') ? USER_READ_ENABLED : USER_READ_DISABLED;
pr_debug("User space counter reading for PMU %s\n", pmu->name); /* * Restrict scheduling to only use the rdpmc on the CPUs the * event can be on. If the test doesn't run on the CPU of the * event then the event will be disabled and the pc->index test * will fail.
*/ if (pmu->cpus != NULL)
cpu_map__set_affinity(pmu->cpus);
/* Make the evsel. */
evsel = perf_evsel__new(&attr); if (!evsel) {
pr_err("User space counter reading for PMU %s [Failed to allocate evsel]\n",
pmu->name);
ret = TEST_FAIL; goto cleanup;
}
err = perf_evsel__open(evsel, NULL, threads); if (err) {
pr_err("User space counter reading for PMU %s [Failed to open evsel]\n",
pmu->name);
ret = TEST_SKIP; goto cleanup;
}
opened = true;
err = perf_evsel__mmap(evsel, 0); if (err) {
pr_err("User space counter reading for PMU %s [Failed to mmap evsel]\n",
pmu->name);
ret = TEST_FAIL; goto cleanup;
}
mapped = true;
pc = perf_evsel__mmap_base(evsel, 0, 0); if (!pc) {
pr_err("User space counter reading for PMU %s [Failed to get mmaped address]\n",
pmu->name);
ret = TEST_FAIL; goto cleanup;
}
if (rdpmc_supported && (!pc->cap_user_rdpmc || !pc->index)) {
pr_err("User space counter reading for PMU %s [Failed unexpected supported counter access %d %d]\n",
pmu->name, pc->cap_user_rdpmc, pc->index);
ret = TEST_FAIL; goto cleanup;
}
if (!rdpmc_supported && pc->cap_user_rdpmc) {
pr_err("User space counter reading for PMU %s [Failed unexpected unsupported counter access %d]\n",
pmu->name, pc->cap_user_rdpmc);
ret = TEST_FAIL; goto cleanup;
}
if (rdpmc_supported && pc->pmc_width < 32) {
pr_err("User space counter reading for PMU %s [Failed width not set %d]\n",
pmu->name, pc->pmc_width);
ret = TEST_FAIL; goto cleanup;
}
perf_evsel__read(evsel, 0, 0, &counts); if (counts.val == 0) {
pr_err("User space counter reading for PMU %s [Failed read]\n", pmu->name);
ret = TEST_FAIL; goto cleanup;
}
for (int i = 0; i < 5; i++) { volatileint count = 0x10000 << i;
__u64 start, end, last = 0;