linux/tools/perf/tests/pmu.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include "parse-events.h"
   3#include "pmu.h"
   4#include "tests.h"
   5#include <errno.h>
   6#include <stdio.h>
   7#include <linux/kernel.h>
   8#include <linux/limits.h>
   9
  10/* Simulated format definitions. */
  11static struct test_format {
  12        const char *name;
  13        const char *value;
  14} test_formats[] = {
  15        { "krava01", "config:0-1,62-63\n", },
  16        { "krava02", "config:10-17\n", },
  17        { "krava03", "config:5\n", },
  18        { "krava11", "config1:0,2,4,6,8,20-28\n", },
  19        { "krava12", "config1:63\n", },
  20        { "krava13", "config1:45-47\n", },
  21        { "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", },
  22        { "krava22", "config2:8,18,48,58\n", },
  23        { "krava23", "config2:28-29,38\n", },
  24};
  25
  26/* Simulated users input. */
  27static struct parse_events_term test_terms[] = {
  28        {
  29                .config    = (char *) "krava01",
  30                .val.num   = 15,
  31                .type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
  32                .type_term = PARSE_EVENTS__TERM_TYPE_USER,
  33        },
  34        {
  35                .config    = (char *) "krava02",
  36                .val.num   = 170,
  37                .type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
  38                .type_term = PARSE_EVENTS__TERM_TYPE_USER,
  39        },
  40        {
  41                .config    = (char *) "krava03",
  42                .val.num   = 1,
  43                .type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
  44                .type_term = PARSE_EVENTS__TERM_TYPE_USER,
  45        },
  46        {
  47                .config    = (char *) "krava11",
  48                .val.num   = 27,
  49                .type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
  50                .type_term = PARSE_EVENTS__TERM_TYPE_USER,
  51        },
  52        {
  53                .config    = (char *) "krava12",
  54                .val.num   = 1,
  55                .type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
  56                .type_term = PARSE_EVENTS__TERM_TYPE_USER,
  57        },
  58        {
  59                .config    = (char *) "krava13",
  60                .val.num   = 2,
  61                .type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
  62                .type_term = PARSE_EVENTS__TERM_TYPE_USER,
  63        },
  64        {
  65                .config    = (char *) "krava21",
  66                .val.num   = 119,
  67                .type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
  68                .type_term = PARSE_EVENTS__TERM_TYPE_USER,
  69        },
  70        {
  71                .config    = (char *) "krava22",
  72                .val.num   = 11,
  73                .type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
  74                .type_term = PARSE_EVENTS__TERM_TYPE_USER,
  75        },
  76        {
  77                .config    = (char *) "krava23",
  78                .val.num   = 2,
  79                .type_val  = PARSE_EVENTS__TERM_TYPE_NUM,
  80                .type_term = PARSE_EVENTS__TERM_TYPE_USER,
  81        },
  82};
  83
  84/*
  85 * Prepare format directory data, exported by kernel
  86 * at /sys/bus/event_source/devices/<dev>/format.
  87 */
  88static char *test_format_dir_get(void)
  89{
  90        static char dir[PATH_MAX];
  91        unsigned int i;
  92
  93        snprintf(dir, PATH_MAX, "/tmp/perf-pmu-test-format-XXXXXX");
  94        if (!mkdtemp(dir))
  95                return NULL;
  96
  97        for (i = 0; i < ARRAY_SIZE(test_formats); i++) {
  98                static char name[PATH_MAX];
  99                struct test_format *format = &test_formats[i];
 100                FILE *file;
 101
 102                scnprintf(name, PATH_MAX, "%s/%s", dir, format->name);
 103
 104                file = fopen(name, "w");
 105                if (!file)
 106                        return NULL;
 107
 108                if (1 != fwrite(format->value, strlen(format->value), 1, file))
 109                        break;
 110
 111                fclose(file);
 112        }
 113
 114        return dir;
 115}
 116
 117/* Cleanup format directory. */
 118static int test_format_dir_put(char *dir)
 119{
 120        char buf[PATH_MAX];
 121        snprintf(buf, PATH_MAX, "rm -f %s/*\n", dir);
 122        if (system(buf))
 123                return -1;
 124
 125        snprintf(buf, PATH_MAX, "rmdir %s\n", dir);
 126        return system(buf);
 127}
 128
 129static struct list_head *test_terms_list(void)
 130{
 131        static LIST_HEAD(terms);
 132        unsigned int i;
 133
 134        for (i = 0; i < ARRAY_SIZE(test_terms); i++)
 135                list_add_tail(&test_terms[i].list, &terms);
 136
 137        return &terms;
 138}
 139
 140int test__pmu(struct test *test __maybe_unused, int subtest __maybe_unused)
 141{
 142        char *format = test_format_dir_get();
 143        LIST_HEAD(formats);
 144        struct list_head *terms = test_terms_list();
 145        int ret;
 146
 147        if (!format)
 148                return -EINVAL;
 149
 150        do {
 151                struct perf_event_attr attr;
 152
 153                memset(&attr, 0, sizeof(attr));
 154
 155                ret = perf_pmu__format_parse(format, &formats);
 156                if (ret)
 157                        break;
 158
 159                ret = perf_pmu__config_terms("perf-pmu-test", &formats, &attr,
 160                                             terms, false, NULL);
 161                if (ret)
 162                        break;
 163
 164                ret = -EINVAL;
 165
 166                if (attr.config  != 0xc00000000002a823)
 167                        break;
 168                if (attr.config1 != 0x8000400000000145)
 169                        break;
 170                if (attr.config2 != 0x0400000020041d07)
 171                        break;
 172
 173                ret = 0;
 174        } while (0);
 175
 176        perf_pmu__del_formats(&formats);
 177        test_format_dir_put(format);
 178        return ret;
 179}
 180