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