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