linux/tools/perf/tests/pfm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Test support for libpfm4 event encodings.
   4 *
   5 * Copyright 2020 Google LLC.
   6 */
   7#include "tests.h"
   8#include "util/debug.h"
   9#include "util/evlist.h"
  10#include "util/pfm.h"
  11
  12#include <linux/kernel.h>
  13
  14#ifdef HAVE_LIBPFM
  15static int test__pfm_events(void);
  16static int test__pfm_group(void);
  17#endif
  18
  19static const struct {
  20        int (*func)(void);
  21        const char *desc;
  22} pfm_testcase_table[] = {
  23#ifdef HAVE_LIBPFM
  24        {
  25                .func = test__pfm_events,
  26                .desc = "test of individual --pfm-events",
  27        },
  28        {
  29                .func = test__pfm_group,
  30                .desc = "test groups of --pfm-events",
  31        },
  32#endif
  33};
  34
  35#ifdef HAVE_LIBPFM
  36static int count_pfm_events(struct perf_evlist *evlist)
  37{
  38        struct perf_evsel *evsel;
  39        int count = 0;
  40
  41        perf_evlist__for_each_entry(evlist, evsel) {
  42                count++;
  43        }
  44        return count;
  45}
  46
  47static int test__pfm_events(void)
  48{
  49        struct evlist *evlist;
  50        struct option opt;
  51        size_t i;
  52        const struct {
  53                const char *events;
  54                int nr_events;
  55        } table[] = {
  56                {
  57                        .events = "",
  58                        .nr_events = 0,
  59                },
  60                {
  61                        .events = "instructions",
  62                        .nr_events = 1,
  63                },
  64                {
  65                        .events = "instructions,cycles",
  66                        .nr_events = 2,
  67                },
  68                {
  69                        .events = "stereolab",
  70                        .nr_events = 0,
  71                },
  72                {
  73                        .events = "instructions,instructions",
  74                        .nr_events = 2,
  75                },
  76                {
  77                        .events = "stereolab,instructions",
  78                        .nr_events = 0,
  79                },
  80                {
  81                        .events = "instructions,stereolab",
  82                        .nr_events = 1,
  83                },
  84        };
  85
  86        for (i = 0; i < ARRAY_SIZE(table); i++) {
  87                evlist = evlist__new();
  88                if (evlist == NULL)
  89                        return -ENOMEM;
  90
  91                opt.value = evlist;
  92                parse_libpfm_events_option(&opt,
  93                                        table[i].events,
  94                                        0);
  95                TEST_ASSERT_EQUAL(table[i].events,
  96                                count_pfm_events(&evlist->core),
  97                                table[i].nr_events);
  98                TEST_ASSERT_EQUAL(table[i].events,
  99                                evlist->core.nr_groups,
 100                                0);
 101
 102                evlist__delete(evlist);
 103        }
 104        return 0;
 105}
 106
 107static int test__pfm_group(void)
 108{
 109        struct evlist *evlist;
 110        struct option opt;
 111        size_t i;
 112        const struct {
 113                const char *events;
 114                int nr_events;
 115                int nr_groups;
 116        } table[] = {
 117                {
 118                        .events = "{},",
 119                        .nr_events = 0,
 120                        .nr_groups = 0,
 121                },
 122                {
 123                        .events = "{instructions}",
 124                        .nr_events = 1,
 125                        .nr_groups = 1,
 126                },
 127                {
 128                        .events = "{instructions},{}",
 129                        .nr_events = 1,
 130                        .nr_groups = 1,
 131                },
 132                {
 133                        .events = "{},{instructions}",
 134                        .nr_events = 1,
 135                        .nr_groups = 1,
 136                },
 137                {
 138                        .events = "{instructions},{instructions}",
 139                        .nr_events = 2,
 140                        .nr_groups = 2,
 141                },
 142                {
 143                        .events = "{instructions,cycles},{instructions,cycles}",
 144                        .nr_events = 4,
 145                        .nr_groups = 2,
 146                },
 147                {
 148                        .events = "{stereolab}",
 149                        .nr_events = 0,
 150                        .nr_groups = 0,
 151                },
 152                {
 153                        .events =
 154                        "{instructions,cycles},{instructions,stereolab}",
 155                        .nr_events = 3,
 156                        .nr_groups = 1,
 157                },
 158                {
 159                        .events = "instructions}",
 160                        .nr_events = 1,
 161                        .nr_groups = 0,
 162                },
 163                {
 164                        .events = "{{instructions}}",
 165                        .nr_events = 0,
 166                        .nr_groups = 0,
 167                },
 168        };
 169
 170        for (i = 0; i < ARRAY_SIZE(table); i++) {
 171                evlist = evlist__new();
 172                if (evlist == NULL)
 173                        return -ENOMEM;
 174
 175                opt.value = evlist;
 176                parse_libpfm_events_option(&opt,
 177                                        table[i].events,
 178                                        0);
 179                TEST_ASSERT_EQUAL(table[i].events,
 180                                count_pfm_events(&evlist->core),
 181                                table[i].nr_events);
 182                TEST_ASSERT_EQUAL(table[i].events,
 183                                evlist->core.nr_groups,
 184                                table[i].nr_groups);
 185
 186                evlist__delete(evlist);
 187        }
 188        return 0;
 189}
 190#endif
 191
 192const char *test__pfm_subtest_get_desc(int i)
 193{
 194        if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
 195                return NULL;
 196        return pfm_testcase_table[i].desc;
 197}
 198
 199int test__pfm_subtest_get_nr(void)
 200{
 201        return (int)ARRAY_SIZE(pfm_testcase_table);
 202}
 203
 204int test__pfm(struct test *test __maybe_unused, int i __maybe_unused)
 205{
 206#ifdef HAVE_LIBPFM
 207        if (i < 0 || i >= (int)ARRAY_SIZE(pfm_testcase_table))
 208                return TEST_FAIL;
 209        return pfm_testcase_table[i].func();
 210#else
 211        return TEST_SKIP;
 212#endif
 213}
 214