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> 6e293a5e8SNamhyung Kim #include <fcntl.h> 7e9dacd63SArnaldo Carvalho de Melo #include <stdio.h> 8877a7a11SArnaldo Carvalho de Melo #include <linux/kernel.h> 9e9dacd63SArnaldo Carvalho de Melo #include <linux/limits.h> 10cff7f956SJiri Olsa 11cff7f956SJiri Olsa /* Simulated format definitions. */ 12cff7f956SJiri Olsa static struct test_format { 13cff7f956SJiri Olsa const char *name; 14cff7f956SJiri Olsa const char *value; 15cff7f956SJiri Olsa } test_formats[] = { 16cff7f956SJiri Olsa { "krava01", "config:0-1,62-63\n", }, 17cff7f956SJiri Olsa { "krava02", "config:10-17\n", }, 18cff7f956SJiri Olsa { "krava03", "config:5\n", }, 19cff7f956SJiri Olsa { "krava11", "config1:0,2,4,6,8,20-28\n", }, 20cff7f956SJiri Olsa { "krava12", "config1:63\n", }, 21cff7f956SJiri Olsa { "krava13", "config1:45-47\n", }, 22cff7f956SJiri Olsa { "krava21", "config2:0-3,10-13,20-23,30-33,40-43,50-53,60-63\n", }, 23cff7f956SJiri Olsa { "krava22", "config2:8,18,48,58\n", }, 24cff7f956SJiri Olsa { "krava23", "config2:28-29,38\n", }, 25cff7f956SJiri Olsa }; 26cff7f956SJiri Olsa 27cff7f956SJiri Olsa /* Simulated users input. */ 286cee6cd3SArnaldo Carvalho de Melo static struct parse_events_term test_terms[] = { 29cff7f956SJiri Olsa { 30cff7f956SJiri Olsa .config = (char *) "krava01", 31cff7f956SJiri Olsa .val.num = 15, 32cff7f956SJiri Olsa .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 33cff7f956SJiri Olsa .type_term = PARSE_EVENTS__TERM_TYPE_USER, 34cff7f956SJiri Olsa }, 35cff7f956SJiri Olsa { 36cff7f956SJiri Olsa .config = (char *) "krava02", 37cff7f956SJiri Olsa .val.num = 170, 38cff7f956SJiri Olsa .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 39cff7f956SJiri Olsa .type_term = PARSE_EVENTS__TERM_TYPE_USER, 40cff7f956SJiri Olsa }, 41cff7f956SJiri Olsa { 42cff7f956SJiri Olsa .config = (char *) "krava03", 43cff7f956SJiri Olsa .val.num = 1, 44cff7f956SJiri Olsa .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 45cff7f956SJiri Olsa .type_term = PARSE_EVENTS__TERM_TYPE_USER, 46cff7f956SJiri Olsa }, 47cff7f956SJiri Olsa { 48cff7f956SJiri Olsa .config = (char *) "krava11", 49cff7f956SJiri Olsa .val.num = 27, 50cff7f956SJiri Olsa .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 51cff7f956SJiri Olsa .type_term = PARSE_EVENTS__TERM_TYPE_USER, 52cff7f956SJiri Olsa }, 53cff7f956SJiri Olsa { 54cff7f956SJiri Olsa .config = (char *) "krava12", 55cff7f956SJiri Olsa .val.num = 1, 56cff7f956SJiri Olsa .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 57cff7f956SJiri Olsa .type_term = PARSE_EVENTS__TERM_TYPE_USER, 58cff7f956SJiri Olsa }, 59cff7f956SJiri Olsa { 60cff7f956SJiri Olsa .config = (char *) "krava13", 61cff7f956SJiri Olsa .val.num = 2, 62cff7f956SJiri Olsa .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 63cff7f956SJiri Olsa .type_term = PARSE_EVENTS__TERM_TYPE_USER, 64cff7f956SJiri Olsa }, 65cff7f956SJiri Olsa { 66cff7f956SJiri Olsa .config = (char *) "krava21", 67cff7f956SJiri Olsa .val.num = 119, 68cff7f956SJiri Olsa .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 69cff7f956SJiri Olsa .type_term = PARSE_EVENTS__TERM_TYPE_USER, 70cff7f956SJiri Olsa }, 71cff7f956SJiri Olsa { 72cff7f956SJiri Olsa .config = (char *) "krava22", 73cff7f956SJiri Olsa .val.num = 11, 74cff7f956SJiri Olsa .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 75cff7f956SJiri Olsa .type_term = PARSE_EVENTS__TERM_TYPE_USER, 76cff7f956SJiri Olsa }, 77cff7f956SJiri Olsa { 78cff7f956SJiri Olsa .config = (char *) "krava23", 79cff7f956SJiri Olsa .val.num = 2, 80cff7f956SJiri Olsa .type_val = PARSE_EVENTS__TERM_TYPE_NUM, 81cff7f956SJiri Olsa .type_term = PARSE_EVENTS__TERM_TYPE_USER, 82cff7f956SJiri Olsa }, 83cff7f956SJiri Olsa }; 84cff7f956SJiri Olsa 85cff7f956SJiri Olsa /* 86cff7f956SJiri Olsa * Prepare format directory data, exported by kernel 87cff7f956SJiri Olsa * at /sys/bus/event_source/devices/<dev>/format. 88cff7f956SJiri Olsa */ 89*f50b8357SIan Rogers static char *test_format_dir_get(char *dir, size_t sz) 90cff7f956SJiri Olsa { 91cff7f956SJiri Olsa unsigned int i; 92cff7f956SJiri Olsa 93*f50b8357SIan Rogers snprintf(dir, sz, "/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++) { 98*f50b8357SIan Rogers 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 { 120*f50b8357SIan Rogers char buf[PATH_MAX + 20]; 121*f50b8357SIan Rogers 122*f50b8357SIan Rogers snprintf(buf, sizeof(buf), "rm -f %s/*\n", dir); 123cff7f956SJiri Olsa if (system(buf)) 124cff7f956SJiri Olsa return -1; 125cff7f956SJiri Olsa 126*f50b8357SIan Rogers snprintf(buf, sizeof(buf), "rmdir %s\n", dir); 127cff7f956SJiri Olsa return system(buf); 128cff7f956SJiri Olsa } 129cff7f956SJiri Olsa 130cff7f956SJiri Olsa static struct list_head *test_terms_list(void) 131cff7f956SJiri Olsa { 132cff7f956SJiri Olsa static LIST_HEAD(terms); 133cff7f956SJiri Olsa unsigned int i; 134cff7f956SJiri Olsa 135be651ed9SArnaldo Carvalho de Melo for (i = 0; i < ARRAY_SIZE(test_terms); i++) 136cff7f956SJiri Olsa list_add_tail(&test_terms[i].list, &terms); 137cff7f956SJiri Olsa 138cff7f956SJiri Olsa return &terms; 139cff7f956SJiri Olsa } 140cff7f956SJiri Olsa 14133f44bfdSIan Rogers static int test__pmu(struct test_suite *test __maybe_unused, int subtest __maybe_unused) 142cff7f956SJiri Olsa { 143*f50b8357SIan Rogers char dir[PATH_MAX]; 144*f50b8357SIan Rogers char *format = test_format_dir_get(dir, sizeof(dir)); 145cff7f956SJiri Olsa LIST_HEAD(formats); 146cff7f956SJiri Olsa struct list_head *terms = test_terms_list(); 147cff7f956SJiri Olsa int ret; 148cff7f956SJiri Olsa 149cff7f956SJiri Olsa if (!format) 150cff7f956SJiri Olsa return -EINVAL; 151cff7f956SJiri Olsa 152cff7f956SJiri Olsa do { 153cff7f956SJiri Olsa struct perf_event_attr attr; 154e293a5e8SNamhyung Kim int fd; 155cff7f956SJiri Olsa 156cff7f956SJiri Olsa memset(&attr, 0, sizeof(attr)); 157cff7f956SJiri Olsa 158e293a5e8SNamhyung Kim fd = open(format, O_DIRECTORY); 159e293a5e8SNamhyung Kim if (fd < 0) { 160e293a5e8SNamhyung Kim ret = fd; 161e293a5e8SNamhyung Kim break; 162e293a5e8SNamhyung Kim } 163e293a5e8SNamhyung Kim ret = perf_pmu__format_parse(fd, &formats); 164cff7f956SJiri Olsa if (ret) 165cff7f956SJiri Olsa break; 166cff7f956SJiri Olsa 1674ac22b48SIan Rogers ret = perf_pmu__config_terms("perf-pmu-test", &formats, &attr, 1684ac22b48SIan Rogers terms, false, NULL); 169cff7f956SJiri Olsa if (ret) 170cff7f956SJiri Olsa break; 171cff7f956SJiri Olsa 172cff7f956SJiri Olsa ret = -EINVAL; 173cff7f956SJiri Olsa 174cff7f956SJiri Olsa if (attr.config != 0xc00000000002a823) 175cff7f956SJiri Olsa break; 176cff7f956SJiri Olsa if (attr.config1 != 0x8000400000000145) 177cff7f956SJiri Olsa break; 178cff7f956SJiri Olsa if (attr.config2 != 0x0400000020041d07) 179cff7f956SJiri Olsa break; 180cff7f956SJiri Olsa 181cff7f956SJiri Olsa ret = 0; 182cff7f956SJiri Olsa } while (0); 183cff7f956SJiri Olsa 184d26383dcSNamhyung Kim perf_pmu__del_formats(&formats); 185cff7f956SJiri Olsa test_format_dir_put(format); 186cff7f956SJiri Olsa return ret; 187cff7f956SJiri Olsa } 188d68f0365SIan Rogers 189d68f0365SIan Rogers DEFINE_SUITE("Parse perf pmu format", pmu); 190