1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sys/types.h> 2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <unistd.h> 3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <sys/prctl.h> 4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "parse-events.h" 6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "evlist.h" 7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "evsel.h" 8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "thread_map.h" 9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "cpumap.h" 10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "tests.h" 11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define CHECK__(x) { \ 13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while ((x) < 0) { \ 14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_debug(#x " failed!\n"); \ 15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; \ 16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } \ 17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define CHECK_NOT_NULL__(x) { \ 20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while ((x) == NULL) { \ 21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_debug(#x " failed!\n"); \ 22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; \ 23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } \ 24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int find_comm(struct perf_evlist *evlist, const char *comm) 27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng union perf_event *event; 29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int i, found; 30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng found = 0; 32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng for (i = 0; i < evlist->nr_mmaps; i++) { 33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) { 34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (event->header.type == PERF_RECORD_COMM && 35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng (pid_t)event->comm.pid == getpid() && 36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng (pid_t)event->comm.tid == getpid() && 37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng strcmp(event->comm.comm, comm) == 0) 38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng found += 1; 39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_evlist__mmap_consume(evlist, i); 40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return found; 43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/** 46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * test__keep_tracking - test using a dummy software event to keep tracking. 47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This function implements a test that checks that tracking events continue 49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * when an event is disabled but a dummy software event is not disabled. If the 50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * test passes %0 is returned, otherwise %-1 is returned. 51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint test__keep_tracking(void) 53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_record_opts opts = { 55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng .mmap_pages = UINT_MAX, 56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng .user_freq = UINT_MAX, 57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng .user_interval = ULLONG_MAX, 58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng .freq = 4000, 59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng .target = { 60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng .uses_mmap = true, 61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng }, 62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng }; 63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct thread_map *threads = NULL; 64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct cpu_map *cpus = NULL; 65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_evlist *evlist = NULL; 66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng struct perf_evsel *evsel = NULL; 67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int found, err = -1; 68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng const char *comm; 69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng threads = thread_map__new(-1, getpid(), UINT_MAX); 71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng CHECK_NOT_NULL__(threads); 72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng cpus = cpu_map__new(NULL); 74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng CHECK_NOT_NULL__(cpus); 75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng evlist = perf_evlist__new(); 77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng CHECK_NOT_NULL__(evlist); 78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_evlist__set_maps(evlist, cpus, threads); 80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng CHECK__(parse_events(evlist, "dummy:u")); 82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng CHECK__(parse_events(evlist, "cycles:u")); 83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_evlist__config(evlist, &opts); 85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng evsel = perf_evlist__first(evlist); 87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng evsel->attr.comm = 1; 89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng evsel->attr.disabled = 1; 90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng evsel->attr.enable_on_exec = 0; 91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (perf_evlist__open(evlist) < 0) { 93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng fprintf(stderr, " (not supported)"); 94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = 0; 95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; 96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng CHECK__(perf_evlist__mmap(evlist, UINT_MAX, false)); 99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* 101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * First, test that a 'comm' event can be found when the event is 102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * enabled. 103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_evlist__enable(evlist); 106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng comm = "Test COMM 1"; 108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0)); 109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_evlist__disable(evlist); 111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng found = find_comm(evlist, comm); 113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (found != 1) { 114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_debug("First time, failed to find tracking event.\n"); 115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; 116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* 119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Secondly, test that a 'comm' event can be found when the event is 120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * disabled with the dummy event still enabled. 121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_evlist__enable(evlist); 124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng evsel = perf_evlist__last(evlist); 126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng CHECK__(perf_evlist__disable_event(evlist, evsel)); 128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng comm = "Test COMM 2"; 130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng CHECK__(prctl(PR_SET_NAME, (unsigned long)comm, 0, 0, 0)); 131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_evlist__disable(evlist); 133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng found = find_comm(evlist, comm); 135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (found != 1) { 136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng pr_debug("Seconf time, failed to find tracking event.\n"); 137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto out_err; 138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng err = 0; 141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_err: 143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (evlist) { 144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_evlist__disable(evlist); 145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_evlist__munmap(evlist); 146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_evlist__close(evlist); 147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng perf_evlist__delete(evlist); 148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (cpus) 150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng cpu_map__delete(cpus); 151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (threads) 152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng thread_map__delete(threads); 153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return err; 155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 156