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