linux/tools/perf/tests/openat-syscall-tp-fields.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <stdbool.h>
   3#include <linux/err.h>
   4#include <linux/string.h>
   5#include <sys/types.h>
   6#include <sys/stat.h>
   7#include <fcntl.h>
   8#include "evlist.h"
   9#include "evsel.h"
  10#include "thread_map.h"
  11#include "record.h"
  12#include "tests.h"
  13#include "debug.h"
  14#include "util/mmap.h"
  15#include <errno.h>
  16#include <perf/mmap.h>
  17
  18#ifndef O_DIRECTORY
  19#define O_DIRECTORY    00200000
  20#endif
  21#ifndef AT_FDCWD
  22#define AT_FDCWD       -100
  23#endif
  24
  25int test__syscall_openat_tp_fields(struct test *test __maybe_unused, int subtest __maybe_unused)
  26{
  27        struct record_opts opts = {
  28                .target = {
  29                        .uid = UINT_MAX,
  30                        .uses_mmap = true,
  31                },
  32                .no_buffering = true,
  33                .freq         = 1,
  34                .mmap_pages   = 256,
  35                .raw_samples  = true,
  36        };
  37        const char *filename = "/etc/passwd";
  38        int flags = O_RDONLY | O_DIRECTORY;
  39        struct evlist *evlist = evlist__new();
  40        struct evsel *evsel;
  41        int err = -1, i, nr_events = 0, nr_polls = 0;
  42        char sbuf[STRERR_BUFSIZE];
  43
  44        if (evlist == NULL) {
  45                pr_debug("%s: evlist__new\n", __func__);
  46                goto out;
  47        }
  48
  49        evsel = evsel__newtp("syscalls", "sys_enter_openat");
  50        if (IS_ERR(evsel)) {
  51                pr_debug("%s: evsel__newtp\n", __func__);
  52                goto out_delete_evlist;
  53        }
  54
  55        evlist__add(evlist, evsel);
  56
  57        err = evlist__create_maps(evlist, &opts.target);
  58        if (err < 0) {
  59                pr_debug("%s: evlist__create_maps\n", __func__);
  60                goto out_delete_evlist;
  61        }
  62
  63        evsel__config(evsel, &opts, NULL);
  64
  65        perf_thread_map__set_pid(evlist->core.threads, 0, getpid());
  66
  67        err = evlist__open(evlist);
  68        if (err < 0) {
  69                pr_debug("perf_evlist__open: %s\n",
  70                         str_error_r(errno, sbuf, sizeof(sbuf)));
  71                goto out_delete_evlist;
  72        }
  73
  74        err = evlist__mmap(evlist, UINT_MAX);
  75        if (err < 0) {
  76                pr_debug("evlist__mmap: %s\n",
  77                         str_error_r(errno, sbuf, sizeof(sbuf)));
  78                goto out_delete_evlist;
  79        }
  80
  81        evlist__enable(evlist);
  82
  83        /*
  84         * Generate the event:
  85         */
  86        openat(AT_FDCWD, filename, flags);
  87
  88        while (1) {
  89                int before = nr_events;
  90
  91                for (i = 0; i < evlist->core.nr_mmaps; i++) {
  92                        union perf_event *event;
  93                        struct mmap *md;
  94
  95                        md = &evlist->mmap[i];
  96                        if (perf_mmap__read_init(&md->core) < 0)
  97                                continue;
  98
  99                        while ((event = perf_mmap__read_event(&md->core)) != NULL) {
 100                                const u32 type = event->header.type;
 101                                int tp_flags;
 102                                struct perf_sample sample;
 103
 104                                ++nr_events;
 105
 106                                if (type != PERF_RECORD_SAMPLE) {
 107                                        perf_mmap__consume(&md->core);
 108                                        continue;
 109                                }
 110
 111                                err = evsel__parse_sample(evsel, event, &sample);
 112                                if (err) {
 113                                        pr_debug("Can't parse sample, err = %d\n", err);
 114                                        goto out_delete_evlist;
 115                                }
 116
 117                                tp_flags = evsel__intval(evsel, &sample, "flags");
 118
 119                                if (flags != tp_flags) {
 120                                        pr_debug("%s: Expected flags=%#x, got %#x\n",
 121                                                 __func__, flags, tp_flags);
 122                                        goto out_delete_evlist;
 123                                }
 124
 125                                goto out_ok;
 126                        }
 127                        perf_mmap__read_done(&md->core);
 128                }
 129
 130                if (nr_events == before)
 131                        evlist__poll(evlist, 10);
 132
 133                if (++nr_polls > 5) {
 134                        pr_debug("%s: no events!\n", __func__);
 135                        goto out_delete_evlist;
 136                }
 137        }
 138out_ok:
 139        err = 0;
 140out_delete_evlist:
 141        evlist__delete(evlist);
 142out:
 143        return err;
 144}
 145