1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 2d944c4eeSBorislav Petkov #include <linux/types.h> 3395c3070SAdrian Hunter #include <unistd.h> 4395c3070SAdrian Hunter #include <sys/prctl.h> 5395c3070SAdrian Hunter 6395c3070SAdrian Hunter #include "parse-events.h" 7395c3070SAdrian Hunter #include "evlist.h" 8395c3070SAdrian Hunter #include "evsel.h" 9395c3070SAdrian Hunter #include "thread_map.h" 10395c3070SAdrian Hunter #include "cpumap.h" 11395c3070SAdrian Hunter #include "tests.h" 12395c3070SAdrian Hunter 13395c3070SAdrian Hunter #define CHECK__(x) { \ 14395c3070SAdrian Hunter while ((x) < 0) { \ 15395c3070SAdrian Hunter pr_debug(#x " failed!\n"); \ 16395c3070SAdrian Hunter goto out_err; \ 17395c3070SAdrian Hunter } \ 18395c3070SAdrian Hunter } 19395c3070SAdrian Hunter 20395c3070SAdrian Hunter #define CHECK_NOT_NULL__(x) { \ 21395c3070SAdrian Hunter while ((x) == NULL) { \ 22395c3070SAdrian Hunter pr_debug(#x " failed!\n"); \ 23395c3070SAdrian Hunter goto out_err; \ 24395c3070SAdrian Hunter } \ 25395c3070SAdrian Hunter } 26395c3070SAdrian Hunter 27395c3070SAdrian Hunter static int find_comm(struct perf_evlist *evlist, const char *comm) 28395c3070SAdrian Hunter { 29395c3070SAdrian Hunter union perf_event *event; 30693d32aeSKan Liang struct perf_mmap *md; 31395c3070SAdrian Hunter int i, found; 32395c3070SAdrian Hunter 33395c3070SAdrian Hunter found = 0; 34395c3070SAdrian Hunter for (i = 0; i < evlist->nr_mmaps; i++) { 35693d32aeSKan Liang md = &evlist->mmap[i]; 36b9bae2c8SKan Liang if (perf_mmap__read_init(md) < 0) 37693d32aeSKan Liang continue; 380019dc87SKan Liang while ((event = perf_mmap__read_event(md)) != NULL) { 39395c3070SAdrian Hunter if (event->header.type == PERF_RECORD_COMM && 40395c3070SAdrian Hunter (pid_t)event->comm.pid == getpid() && 41395c3070SAdrian Hunter (pid_t)event->comm.tid == getpid() && 42395c3070SAdrian Hunter strcmp(event->comm.comm, comm) == 0) 43395c3070SAdrian Hunter found += 1; 44d6ace3dfSKan Liang perf_mmap__consume(md); 45395c3070SAdrian Hunter } 46693d32aeSKan Liang perf_mmap__read_done(md); 47395c3070SAdrian Hunter } 48395c3070SAdrian Hunter return found; 49395c3070SAdrian Hunter } 50395c3070SAdrian Hunter 51395c3070SAdrian Hunter /** 52395c3070SAdrian Hunter * test__keep_tracking - test using a dummy software event to keep tracking. 53395c3070SAdrian Hunter * 54395c3070SAdrian Hunter * This function implements a test that checks that tracking events continue 55395c3070SAdrian Hunter * when an event is disabled but a dummy software event is not disabled. If the 56395c3070SAdrian Hunter * test passes %0 is returned, otherwise %-1 is returned. 57395c3070SAdrian Hunter */ 5881f17c90SArnaldo Carvalho de Melo int test__keep_tracking(struct test *test __maybe_unused, int subtest __maybe_unused) 59395c3070SAdrian Hunter { 60b4006796SArnaldo Carvalho de Melo struct record_opts opts = { 61395c3070SAdrian Hunter .mmap_pages = UINT_MAX, 62395c3070SAdrian Hunter .user_freq = UINT_MAX, 63395c3070SAdrian Hunter .user_interval = ULLONG_MAX, 64395c3070SAdrian Hunter .target = { 65395c3070SAdrian Hunter .uses_mmap = true, 66395c3070SAdrian Hunter }, 67395c3070SAdrian Hunter }; 689749b90eSJiri Olsa struct perf_thread_map *threads = NULL; 69f854839bSJiri Olsa struct perf_cpu_map *cpus = NULL; 70395c3070SAdrian Hunter struct perf_evlist *evlist = NULL; 71395c3070SAdrian Hunter struct perf_evsel *evsel = NULL; 72395c3070SAdrian Hunter int found, err = -1; 73395c3070SAdrian Hunter const char *comm; 74395c3070SAdrian Hunter 75395c3070SAdrian Hunter threads = thread_map__new(-1, getpid(), UINT_MAX); 76395c3070SAdrian Hunter CHECK_NOT_NULL__(threads); 77395c3070SAdrian Hunter 78395c3070SAdrian Hunter cpus = cpu_map__new(NULL); 79395c3070SAdrian Hunter CHECK_NOT_NULL__(cpus); 80395c3070SAdrian Hunter 81395c3070SAdrian Hunter evlist = perf_evlist__new(); 82395c3070SAdrian Hunter CHECK_NOT_NULL__(evlist); 83395c3070SAdrian Hunter 84395c3070SAdrian Hunter perf_evlist__set_maps(evlist, cpus, threads); 85395c3070SAdrian Hunter 86b39b8393SJiri Olsa CHECK__(parse_events(evlist, "dummy:u", NULL)); 87b39b8393SJiri Olsa CHECK__(parse_events(evlist, "cycles:u", NULL)); 88395c3070SAdrian Hunter 89e68ae9cfSArnaldo Carvalho de Melo perf_evlist__config(evlist, &opts, NULL); 90395c3070SAdrian Hunter 91395c3070SAdrian Hunter evsel = perf_evlist__first(evlist); 92395c3070SAdrian Hunter 93395c3070SAdrian Hunter evsel->attr.comm = 1; 94395c3070SAdrian Hunter evsel->attr.disabled = 1; 95395c3070SAdrian Hunter evsel->attr.enable_on_exec = 0; 96395c3070SAdrian Hunter 97395c3070SAdrian Hunter if (perf_evlist__open(evlist) < 0) { 98597bdeb4SWang Nan pr_debug("Unable to open dummy and cycles event\n"); 99597bdeb4SWang Nan err = TEST_SKIP; 100395c3070SAdrian Hunter goto out_err; 101395c3070SAdrian Hunter } 102395c3070SAdrian Hunter 103f74b9d3aSWang Nan CHECK__(perf_evlist__mmap(evlist, UINT_MAX)); 104395c3070SAdrian Hunter 105395c3070SAdrian Hunter /* 106395c3070SAdrian Hunter * First, test that a 'comm' event can be found when the event is 107395c3070SAdrian Hunter * enabled. 108395c3070SAdrian Hunter */ 109395c3070SAdrian Hunter 110395c3070SAdrian Hunter perf_evlist__enable(evlist); 111395c3070SAdrian Hunter 112395c3070SAdrian Hunter comm = "Test COMM 1"; 113395c3070SAdrian Hunter CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0)); 114395c3070SAdrian Hunter 115395c3070SAdrian Hunter perf_evlist__disable(evlist); 116395c3070SAdrian Hunter 117395c3070SAdrian Hunter found = find_comm(evlist, comm); 118395c3070SAdrian Hunter if (found != 1) { 119395c3070SAdrian Hunter pr_debug("First time, failed to find tracking event.\n"); 120395c3070SAdrian Hunter goto out_err; 121395c3070SAdrian Hunter } 122395c3070SAdrian Hunter 123395c3070SAdrian Hunter /* 124395c3070SAdrian Hunter * Secondly, test that a 'comm' event can be found when the event is 125395c3070SAdrian Hunter * disabled with the dummy event still enabled. 126395c3070SAdrian Hunter */ 127395c3070SAdrian Hunter 128395c3070SAdrian Hunter perf_evlist__enable(evlist); 129395c3070SAdrian Hunter 130395c3070SAdrian Hunter evsel = perf_evlist__last(evlist); 131395c3070SAdrian Hunter 132d2190a80SJiri Olsa CHECK__(perf_evsel__disable(evsel)); 133395c3070SAdrian Hunter 134395c3070SAdrian Hunter comm = "Test COMM 2"; 135395c3070SAdrian Hunter CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0)); 136395c3070SAdrian Hunter 137395c3070SAdrian Hunter perf_evlist__disable(evlist); 138395c3070SAdrian Hunter 139395c3070SAdrian Hunter found = find_comm(evlist, comm); 140395c3070SAdrian Hunter if (found != 1) { 141395c3070SAdrian Hunter pr_debug("Seconf time, failed to find tracking event.\n"); 142395c3070SAdrian Hunter goto out_err; 143395c3070SAdrian Hunter } 144395c3070SAdrian Hunter 145395c3070SAdrian Hunter err = 0; 146395c3070SAdrian Hunter 147395c3070SAdrian Hunter out_err: 148395c3070SAdrian Hunter if (evlist) { 149395c3070SAdrian Hunter perf_evlist__disable(evlist); 150395c3070SAdrian Hunter perf_evlist__delete(evlist); 15103ad9747SArnaldo Carvalho de Melo } else { 152f30a79b0SJiri Olsa cpu_map__put(cpus); 153186fbb74SJiri Olsa thread_map__put(threads); 15403ad9747SArnaldo Carvalho de Melo } 155395c3070SAdrian Hunter 156395c3070SAdrian Hunter return err; 157395c3070SAdrian Hunter } 158