^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <limits.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <sys/prctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <perf/cpumap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <perf/evlist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <perf/mmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "parse-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "record.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "thread_map.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "tests.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "util/mmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define CHECK__(x) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) while ((x) < 0) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) pr_debug(#x " failed!\n"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) goto out_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define CHECK_NOT_NULL__(x) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) while ((x) == NULL) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) pr_debug(#x " failed!\n"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) goto out_err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static int find_comm(struct evlist *evlist, const char *comm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) union perf_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct mmap *md;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) int i, found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) for (i = 0; i < evlist->core.nr_mmaps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) md = &evlist->mmap[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (perf_mmap__read_init(&md->core) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) while ((event = perf_mmap__read_event(&md->core)) != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (event->header.type == PERF_RECORD_COMM &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) (pid_t)event->comm.pid == getpid() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) (pid_t)event->comm.tid == getpid() &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) strcmp(event->comm.comm, comm) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) found += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) perf_mmap__consume(&md->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) perf_mmap__read_done(&md->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * test__keep_tracking - test using a dummy software event to keep tracking.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * This function implements a test that checks that tracking events continue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * when an event is disabled but a dummy software event is not disabled. If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * test passes %0 is returned, otherwise %-1 is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct record_opts opts = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .mmap_pages = UINT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .user_freq = UINT_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .user_interval = ULLONG_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .target = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .uses_mmap = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct perf_thread_map *threads = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct perf_cpu_map *cpus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) struct evlist *evlist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct evsel *evsel = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) int found, err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) const char *comm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) threads = thread_map__new(-1, getpid(), UINT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) CHECK_NOT_NULL__(threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) cpus = perf_cpu_map__new(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) CHECK_NOT_NULL__(cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) evlist = evlist__new();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) CHECK_NOT_NULL__(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) perf_evlist__set_maps(&evlist->core, cpus, threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) CHECK__(parse_events(evlist, "dummy:u", NULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) CHECK__(parse_events(evlist, "cycles:u", NULL));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) perf_evlist__config(evlist, &opts, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) evsel = evlist__first(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) evsel->core.attr.comm = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) evsel->core.attr.disabled = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) evsel->core.attr.enable_on_exec = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (evlist__open(evlist) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) pr_debug("Unable to open dummy and cycles event\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) err = TEST_SKIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) CHECK__(evlist__mmap(evlist, UINT_MAX));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * First, test that a 'comm' event can be found when the event is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) evlist__enable(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) comm = "Test COMM 1";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) evlist__disable(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) found = find_comm(evlist, comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (found != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) pr_debug("First time, failed to find tracking event.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * Secondly, test that a 'comm' event can be found when the event is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * disabled with the dummy event still enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) evlist__enable(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) evsel = evlist__last(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) CHECK__(evsel__disable(evsel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) comm = "Test COMM 2";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) evlist__disable(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) found = find_comm(evlist, comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) if (found != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) pr_debug("Second time, failed to find tracking event.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) goto out_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) out_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (evlist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) evlist__disable(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) evlist__delete(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) perf_cpu_map__put(cpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) perf_thread_map__put(threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }