diff options
Diffstat (limited to 'tools/perf/tests')
-rw-r--r-- | tools/perf/tests/Build | 1 | ||||
-rw-r--r-- | tools/perf/tests/bitmap.c | 2 | ||||
-rw-r--r-- | tools/perf/tests/bpf.c | 2 | ||||
-rw-r--r-- | tools/perf/tests/builtin-test.c | 15 | ||||
-rw-r--r-- | tools/perf/tests/dlfilter-test.c | 416 | ||||
-rw-r--r-- | tools/perf/tests/dso-data.c | 14 | ||||
-rw-r--r-- | tools/perf/tests/llvm.c | 7 | ||||
-rw-r--r-- | tools/perf/tests/mem2node.c | 2 | ||||
-rw-r--r-- | tools/perf/tests/parse-events.c | 92 | ||||
-rw-r--r-- | tools/perf/tests/pmu-events.c | 699 | ||||
-rw-r--r-- | tools/perf/tests/shell/lib/probe_vfs_getname.sh | 2 | ||||
-rwxr-xr-x | tools/perf/tests/shell/pipe_test.sh | 69 | ||||
-rwxr-xr-x | tools/perf/tests/shell/record+zstd_comp_decomp.sh | 4 | ||||
-rw-r--r-- | tools/perf/tests/tests.h | 1 | ||||
-rw-r--r-- | tools/perf/tests/topology.c | 4 |
15 files changed, 1110 insertions, 220 deletions
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build index 650aec19d490..803ca426f8e6 100644 --- a/tools/perf/tests/Build +++ b/tools/perf/tests/Build @@ -64,6 +64,7 @@ perf-y += parse-metric.o perf-y += pe-file-parsing.o perf-y += expand-cgroup.o perf-y += perf-time-to-tsc.o +perf-y += dlfilter-test.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir) diff --git a/tools/perf/tests/bitmap.c b/tools/perf/tests/bitmap.c index 96c137360918..12b805efdca0 100644 --- a/tools/perf/tests/bitmap.c +++ b/tools/perf/tests/bitmap.c @@ -14,7 +14,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) unsigned long *bm = NULL; int i; - bm = bitmap_alloc(nbits); + bm = bitmap_zalloc(nbits); if (map && bm) { for (i = 0; i < map->nr; i++) diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c index dbf5f5215abe..fa03ff0dc083 100644 --- a/tools/perf/tests/bpf.c +++ b/tools/perf/tests/bpf.c @@ -192,7 +192,7 @@ static int do_test(struct bpf_object *obj, int (*func)(void), } if (count != expect * evlist->core.nr_entries) { - pr_debug("BPF filter result incorrect, expected %d, got %d samples\n", expect, count); + pr_debug("BPF filter result incorrect, expected %d, got %d samples\n", expect * evlist->core.nr_entries, count); goto out_delete_evlist; } diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c index 5e6242576236..da7dc5e45d0c 100644 --- a/tools/perf/tests/builtin-test.c +++ b/tools/perf/tests/builtin-test.c @@ -361,6 +361,10 @@ static struct test generic_tests[] = { .is_supported = test__tsc_is_supported, }, { + .desc = "dlfilter C API", + .func = test__dlfilter, + }, + { .func = NULL, }, }; @@ -594,7 +598,8 @@ static int shell_test__run(struct test *test, int subdir __maybe_unused) return WEXITSTATUS(err) == 2 ? TEST_SKIP : TEST_FAIL; } -static int run_shell_tests(int argc, const char *argv[], int i, int width) +static int run_shell_tests(int argc, const char *argv[], int i, int width, + struct intlist *skiplist) { struct dirent **entlist; struct dirent *ent; @@ -628,6 +633,12 @@ static int run_shell_tests(int argc, const char *argv[], int i, int width) st.file = ent->d_name; pr_info("%2d: %-*s:", i, width, test.desc); + + if (intlist__find(skiplist, i)) { + color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip (user override)\n"); + continue; + } + test_and_print(&test, false, -1); } @@ -727,7 +738,7 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist) } } - return run_shell_tests(argc, argv, i, width); + return run_shell_tests(argc, argv, i, width, skiplist); } static int perf_test__list_shell(int argc, const char **argv, int i) diff --git a/tools/perf/tests/dlfilter-test.c b/tools/perf/tests/dlfilter-test.c new file mode 100644 index 000000000000..bc03b5df6828 --- /dev/null +++ b/tools/perf/tests/dlfilter-test.c @@ -0,0 +1,416 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Test dlfilter C API. A perf.data file is synthesized and then processed + * by perf script with a dlfilter named dlfilter-test-api-v0.so. Also a C file + * is compiled to provide a dso to match the synthesized perf.data file. + */ + +#include <linux/compiler.h> +#include <linux/kernel.h> +#include <linux/string.h> +#include <linux/perf_event.h> +#include <internal/lib.h> +#include <subcmd/exec-cmd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> +#include <inttypes.h> +#include <libgen.h> +#include <string.h> +#include <errno.h> +#include "debug.h" +#include "tool.h" +#include "event.h" +#include "header.h" +#include "machine.h" +#include "dso.h" +#include "map.h" +#include "symbol.h" +#include "synthetic-events.h" +#include "util.h" +#include "archinsn.h" +#include "dlfilter.h" +#include "tests.h" + +#define MAP_START 0x400000 + +struct test_data { + struct perf_tool tool; + struct machine *machine; + int fd; + u64 foo; + u64 bar; + u64 ip; + u64 addr; + char perf[PATH_MAX]; + char perf_data_file_name[PATH_MAX]; + char c_file_name[PATH_MAX]; + char prog_file_name[PATH_MAX]; + char dlfilters[PATH_MAX]; +}; + +static int test_result(const char *msg, int ret) +{ + pr_debug("%s\n", msg); + return ret; +} + +static int process(struct perf_tool *tool, union perf_event *event, + struct perf_sample *sample __maybe_unused, + struct machine *machine __maybe_unused) +{ + struct test_data *td = container_of(tool, struct test_data, tool); + int fd = td->fd; + + if (writen(fd, event, event->header.size) != event->header.size) + return -1; + + return 0; +} + +#define MAXCMD 4096 +#define REDIRECT_TO_DEV_NULL " >/dev/null 2>&1" + +static __printf(1, 2) int system_cmd(const char *fmt, ...) +{ + char cmd[MAXCMD + sizeof(REDIRECT_TO_DEV_NULL)]; + int ret; + + va_list args; + + va_start(args, fmt); + ret = vsnprintf(cmd, MAXCMD, fmt, args); + va_end(args); + + if (ret <= 0 || ret >= MAXCMD) + return -1; + + if (!verbose) + strcat(cmd, REDIRECT_TO_DEV_NULL); + + pr_debug("Command: %s\n", cmd); + ret = system(cmd); + if (ret) + pr_debug("Failed with return value %d\n", ret); + + return ret; +} + +static bool have_gcc(void) +{ + pr_debug("Checking for gcc\n"); + return !system_cmd("gcc --version"); +} + +static int write_attr(struct test_data *td, u64 sample_type, u64 *id) +{ + struct perf_event_attr attr = { + .size = sizeof(attr), + .type = PERF_TYPE_HARDWARE, + .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS, + .sample_type = sample_type, + .sample_period = 1, + }; + + return perf_event__synthesize_attr(&td->tool, &attr, 1, id, process); +} + +static int write_comm(int fd, pid_t pid, pid_t tid, const char *comm_str) +{ + struct perf_record_comm comm; + ssize_t sz = sizeof(comm); + + comm.header.type = PERF_RECORD_COMM; + comm.header.misc = PERF_RECORD_MISC_USER; + comm.header.size = sz; + + comm.pid = pid; + comm.tid = tid; + strncpy(comm.comm, comm_str, 16); + + if (writen(fd, &comm, sz) != sz) { + pr_debug("%s failed\n", __func__); + return -1; + } + + return 0; +} + +static int write_mmap(int fd, pid_t pid, pid_t tid, u64 start, u64 len, u64 pgoff, + const char *filename) +{ + char buf[PERF_SAMPLE_MAX_SIZE]; + struct perf_record_mmap *mmap = (struct perf_record_mmap *)buf; + size_t fsz = roundup(strlen(filename) + 1, 8); + ssize_t sz = sizeof(*mmap) - sizeof(mmap->filename) + fsz; + + mmap->header.type = PERF_RECORD_MMAP; + mmap->header.misc = PERF_RECORD_MISC_USER; + mmap->header.size = sz; + + mmap->pid = pid; + mmap->tid = tid; + mmap->start = start; + mmap->len = len; + mmap->pgoff = pgoff; + strncpy(mmap->filename, filename, sizeof(mmap->filename)); + + if (writen(fd, mmap, sz) != sz) { + pr_debug("%s failed\n", __func__); + return -1; + } + + return 0; +} + +static int write_sample(struct test_data *td, u64 sample_type, u64 id, pid_t pid, pid_t tid) +{ + char buf[PERF_SAMPLE_MAX_SIZE]; + union perf_event *event = (union perf_event *)buf; + struct perf_sample sample = { + .ip = td->ip, + .addr = td->addr, + .id = id, + .time = 1234567890, + .cpu = 31, + .pid = pid, + .tid = tid, + .period = 543212345, + .stream_id = 101, + }; + int err; + + event->header.type = PERF_RECORD_SAMPLE; + event->header.misc = PERF_RECORD_MISC_USER; + event->header.size = perf_event__sample_event_size(&sample, sample_type, 0); + err = perf_event__synthesize_sample(event, sample_type, 0, &sample); + if (err) + return test_result("perf_event__synthesize_sample() failed", TEST_FAIL); + + err = process(&td->tool, event, &sample, td->machine); + if (err) + return test_result("Failed to write sample", TEST_FAIL); + + return TEST_OK; +} + +static void close_fd(int fd) +{ + if (fd >= 0) + close(fd); +} + +static const char *prog = "int bar(){};int foo(){bar();};int main(){foo();return 0;}"; + +static int write_prog(char *file_name) +{ + int fd = creat(file_name, 0644); + ssize_t n = strlen(prog); + bool err = fd < 0 || writen(fd, prog, n) != n; + + close_fd(fd); + return err ? -1 : 0; +} + +static int get_dlfilters_path(char *buf, size_t sz) +{ + char perf[PATH_MAX]; + char path[PATH_MAX]; + char *perf_path; + char *exec_path; + + perf_exe(perf, sizeof(perf)); + perf_path = dirname(perf); + snprintf(path, sizeof(path), "%s/dlfilters/dlfilter-test-api-v0.so", perf_path); + if (access(path, R_OK)) { + exec_path = get_argv_exec_path(); + if (!exec_path) + return -1; + snprintf(path, sizeof(path), "%s/dlfilters/dlfilter-test-api-v0.so", exec_path); + free(exec_path); + if (access(path, R_OK)) + return -1; + } + strlcpy(buf, dirname(path), sz); + return 0; +} + +static int check_filter_desc(struct test_data *td) +{ + char *long_desc = NULL; + char *desc = NULL; + int ret; + + if (get_filter_desc(td->dlfilters, "dlfilter-test-api-v0.so", &desc, &long_desc) && + long_desc && !strcmp(long_desc, "Filter used by the 'dlfilter C API' perf test") && + desc && !strcmp(desc, "dlfilter to test v0 C API")) + ret = 0; + else + ret = -1; + + free(desc); + free(long_desc); + return ret; +} + +static int get_ip_addr(struct test_data *td) +{ + struct map *map; + struct symbol *sym; + + map = dso__new_map(td->prog_file_name); + if (!map) + return -1; + + sym = map__find_symbol_by_name(map, "foo"); + if (sym) + td->foo = sym->start; + + sym = map__find_symbol_by_name(map, "bar"); + if (sym) + td->bar = sym->start; + + map__put(map); + + td->ip = MAP_START + td->foo; + td->addr = MAP_START + td->bar; + + return td->foo && td->bar ? 0 : -1; +} + +static int do_run_perf_script(struct test_data *td, int do_early) +{ + return system_cmd("%s script -i %s " + "--dlfilter %s/dlfilter-test-api-v0.so " + "--dlarg first " + "--dlarg %d " + "--dlarg %" PRIu64 " " + "--dlarg %" PRIu64 " " + "--dlarg %d " + "--dlarg last", + td->perf, td->perf_data_file_name, td->dlfilters, + verbose, td->ip, td->addr, do_early); +} + +static int run_perf_script(struct test_data *td) +{ + int do_early; + int err; + + for (do_early = 0; do_early < 3; do_early++) { + err = do_run_perf_script(td, do_early); + if (err) + return err; + } + return 0; +} + +#define TEST_SAMPLE_TYPE (PERF_SAMPLE_IP | PERF_SAMPLE_TID | \ + PERF_SAMPLE_IDENTIFIER | PERF_SAMPLE_TIME | \ + PERF_SAMPLE_ADDR | PERF_SAMPLE_CPU | \ + PERF_SAMPLE_PERIOD | PERF_SAMPLE_STREAM_ID) + +static int test__dlfilter_test(struct test_data *td) +{ + u64 sample_type = TEST_SAMPLE_TYPE; + pid_t pid = 12345; + pid_t tid = 12346; + u64 id = 99; + int err; + + if (get_dlfilters_path(td->dlfilters, PATH_MAX)) + return test_result("dlfilters not found", TEST_SKIP); + + if (check_filter_desc(td)) + return test_result("Failed to get expected filter description", TEST_FAIL); + + if (!have_gcc()) + return test_result("gcc not found", TEST_SKIP); + + pr_debug("dlfilters path: %s\n", td->dlfilters); + + if (write_prog(td->c_file_name)) + return test_result("Failed to write test C file", TEST_FAIL); + + if (verbose > 1) + system_cmd("cat %s ; echo", td->c_file_name); + + if (system_cmd("gcc -g -o %s %s", td->prog_file_name, td->c_file_name)) + return TEST_FAIL; + + if (verbose > 2) + system_cmd("objdump -x -dS %s", td->prog_file_name); + + if (get_ip_addr(td)) + return test_result("Failed to find program symbols", TEST_FAIL); + + pr_debug("Creating new host machine structure\n"); + td->machine = machine__new_host(); + td->machine->env = &perf_env; + + td->fd = creat(td->perf_data_file_name, 0644); + if (td->fd < 0) + return test_result("Failed to create test perf.data file", TEST_FAIL); + + err = perf_header__write_pipe(td->fd); + if (err < 0) + return test_result("perf_header__write_pipe() failed", TEST_FAIL); + + err = write_attr(td, sample_type, &id); + if (err) + return test_result("perf_event__synthesize_attr() failed", TEST_FAIL); + + if (write_comm(td->fd, pid, tid, "test-prog")) + return TEST_FAIL; + + if (write_mmap(td->fd, pid, tid, MAP_START, 0x10000, 0, td->prog_file_name)) + return TEST_FAIL; + + if (write_sample(td, sample_type, id, pid, tid) != TEST_OK) + return TEST_FAIL; + + if (verbose > 1) + system_cmd("%s script -i %s -D", td->perf, td->perf_data_file_name); + + err = run_perf_script(td); + if (err) + return TEST_FAIL; + + return TEST_OK; +} + +static void unlink_path(const char *path) +{ + if (*path) + unlink(path); +} + +static void test_data__free(struct test_data *td) +{ + machine__delete(td->machine); + close_fd(td->fd); + if (verbose <= 2) { + unlink_path(td->c_file_name); + unlink_path(td->prog_file_name); + unlink_path(td->perf_data_file_name); + } +} + +int test__dlfilter(struct test *test __maybe_unused, int subtest __maybe_unused) +{ + struct test_data td = {.fd = -1}; + int pid = getpid(); + int err; + + perf_exe(td.perf, sizeof(td.perf)); + + snprintf(td.perf_data_file_name, PATH_MAX, "/tmp/dlfilter-test-%u-perf-data", pid); + snprintf(td.c_file_name, PATH_MAX, "/tmp/dlfilter-test-%u-prog.c", pid); + snprintf(td.prog_file_name, PATH_MAX, "/tmp/dlfilter-test-%u-prog", pid); + + err = test__dlfilter_test(&td); + test_data__free(&td); + return err; +} diff --git a/tools/perf/tests/dso-data.c b/tools/perf/tests/dso-data.c index 627c1aaf1c9e..43e1b01e5afc 100644 --- a/tools/perf/tests/dso-data.c +++ b/tools/perf/tests/dso-data.c @@ -308,10 +308,20 @@ int test__dso_data_cache(struct test *test __maybe_unused, int subtest __maybe_u return 0; } +static long new_limit(int count) +{ + int fd = open("/dev/null", O_RDONLY); + long ret = fd; + if (count > 0) + ret = new_limit(--count); + close(fd); + return ret; +} + int test__dso_data_reopen(struct test *test __maybe_unused, int subtest __maybe_unused) { struct machine machine; - long nr_end, nr = open_files_cnt(); + long nr_end, nr = open_files_cnt(), lim = new_limit(3); int fd, fd_extra; #define dso_0 (dsos[0]) @@ -334,7 +344,7 @@ int test__dso_data_reopen(struct test *test __maybe_unused, int subtest __maybe_ /* Make sure we are able to open 3 fds anyway */ TEST_ASSERT_VAL("failed to set file limit", - !set_fd_limit((nr + 3))); + !set_fd_limit((lim))); TEST_ASSERT_VAL("failed to create dsos\n", !dsos__create(3, TEST_FILE_SIZE)); diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c index 98da8a8757ab..33e43cce9064 100644 --- a/tools/perf/tests/llvm.c +++ b/tools/perf/tests/llvm.c @@ -67,12 +67,11 @@ test_llvm__fetch_bpf_obj(void **p_obj_buf, /* * Skip this test if user's .perfconfig doesn't set [llvm] section - * and clang is not found in $PATH, and this is not perf test -v + * and clang is not found in $PATH */ - if (!force && (verbose <= 0 && - !llvm_param.user_set_param && + if (!force && (!llvm_param.user_set_param && llvm__search_clang())) { - pr_debug("No clang and no verbosive, skip this test\n"); + pr_debug("No clang, skip this test\n"); return TEST_SKIP; } diff --git a/tools/perf/tests/mem2node.c b/tools/perf/tests/mem2node.c index a258bd51f1a4..e4d0d58b97f8 100644 --- a/tools/perf/tests/mem2node.c +++ b/tools/perf/tests/mem2node.c @@ -27,7 +27,7 @@ static unsigned long *get_bitmap(const char *str, int nbits) unsigned long *bm = NULL; int i; - bm = bitmap_alloc(nbits); + bm = bitmap_zalloc(nbits); if (map && bm) { for (i = 0; i < map->nr; i++) { diff --git a/tools/perf/tests/parse-events.c b/tools/perf/tests/parse-events.c index 8d4866739255..fd3556cc9ad4 100644 --- a/tools/perf/tests/parse-events.c +++ b/tools/perf/tests/parse-events.c @@ -9,6 +9,7 @@ #include "pmu-hybrid.h" #include <dirent.h> #include <errno.h> +#include "fncache.h" #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> @@ -2194,9 +2195,91 @@ static int test_pmu_events(void) return ret; } +static bool test_alias(char **event, char **alias) +{ + char path[PATH_MAX]; + DIR *dir; + struct dirent *dent; + const char *sysfs = sysfs__mountpoint(); + char buf[128]; + FILE *file; + + if (!sysfs) + return false; + + snprintf(path, PATH_MAX, "%s/bus/event_source/devices/", sysfs); + dir = opendir(path); + if (!dir) + return false; + + while ((dent = readdir(dir))) { + if (!strcmp(dent->d_name, ".") || + !strcmp(dent->d_name, "..")) + continue; + + snprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/alias", + sysfs, dent->d_name); + + if (!file_available(path)) + continue; + + file = fopen(path, "r"); + if (!file) + continue; + + if (!fgets(buf, sizeof(buf), file)) { + fclose(file); + continue; + } + + /* Remove the last '\n' */ + buf[strlen(buf) - 1] = 0; + + fclose(file); + *event = strdup(dent->d_name); + *alias = strdup(buf); + closedir(dir); + + if (*event == NULL || *alias == NULL) { + free(*event); + free(*alias); + return false; + } + + return true; + } + + closedir(dir); + return false; +} + +static int test__checkevent_pmu_events_alias(struct evlist *evlist) +{ + struct evsel *evsel1 = evlist__first(evlist); + struct evsel *evsel2 = evlist__last(evlist); + + TEST_ASSERT_VAL("wrong type", evsel1->core.attr.type == evsel2->core.attr.type); + TEST_ASSERT_VAL("wrong config", evsel1->core.attr.config == evsel2->core.attr.config); + return 0; +} + +static int test_pmu_events_alias(char *event, char *alias) +{ + struct evlist_test e = { .id = 0, }; + char name[2 * NAME_MAX + 20]; + + snprintf(name, sizeof(name), "%s/event=1/,%s/event=1/", + event, alias); + + e.name = name; + e.check = test__checkevent_pmu_events_alias; + return test_event(&e); +} + int test__parse_events(struct test *test __maybe_unused, int subtest __maybe_unused) { int ret1, ret2 = 0; + char *event, *alias; #define TEST_EVENTS(tests) \ do { \ @@ -2221,6 +2304,15 @@ do { \ return ret; } + if (test_alias(&event, &alias)) { + int ret = test_pmu_events_alias(event, alias); + + free(event); + free(alias); + if (ret) + return ret; + } + ret1 = test_terms(test__terms, ARRAY_SIZE(test__terms)); if (!ret2) ret2 = ret1; diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index b8aff8fb50d8..43743cf719ef 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -28,110 +28,190 @@ struct perf_pmu_test_event { * be set in the alias. */ const char *alias_long_desc; + + /* PMU which we should match against */ + const char *matching_pmu; }; -static struct perf_pmu_test_event test_cpu_events[] = { - { - .event = { - .name = "bp_l1_btb_correct", - .event = "event=0x8a", - .desc = "L1 BTB Correction", - .topic = "branch", - }, - .alias_str = "event=0x8a", - .alias_long_desc = "L1 BTB Correction", +struct perf_pmu_test_pmu { + struct perf_pmu pmu; + struct perf_pmu_test_event const *aliases[10]; +}; + +static const struct perf_pmu_test_event bp_l1_btb_correct = { + .event = { + .name = "bp_l1_btb_correct", + .event = "event=0x8a", + .desc = "L1 BTB Correction", + .topic = "branch", }, - { - .event = { - .name = "bp_l2_btb_correct", - .event = "event=0x8b", - .desc = "L2 BTB Correction", - .topic = "branch", - }, - .alias_str = "event=0x8b", - .alias_long_desc = "L2 BTB Correction", + .alias_str = "event=0x8a", + .alias_long_desc = "L1 BTB Correction", +}; + +static const struct perf_pmu_test_event bp_l2_btb_correct = { + .event = { + .name = "bp_l2_btb_correct", + .event = "event=0x8b", + .desc = "L2 BTB Correction", + .topic = "branch", }, - { - .event = { - .name = "segment_reg_loads.any", - .event = "umask=0x80,period=200000,event=0x6", - .desc = "Number of segment register loads", - .topic = "other", - }, - .alias_str = "umask=0x80,(null)=0x30d40,event=0x6", - .alias_long_desc = "Number of segment register loads", + .alias_str = "event=0x8b", + .alias_long_desc = "L2 BTB Correction", +}; + +static const struct perf_pmu_test_event segment_reg_loads_any = { + .event = { + .name = "segment_reg_loads.any", + .event = "umask=0x80,period=200000,event=0x6", + .desc = "Number of segment register loads", + .topic = "other", }, - { - .event = { - .name = "dispatch_blocked.any", - .event = "umask=0x20,period=200000,event=0x9", - .desc = "Memory cluster signals to block micro-op dispatch for any reason", - .topic = "other", - }, - .alias_str = "umask=0x20,(null)=0x30d40,event=0x9", - .alias_long_desc = "Memory cluster signals to block micro-op dispatch for any reason", + .alias_str = "umask=0x80,(null)=0x30d40,event=0x6", + .alias_long_desc = "Number of segment register loads", +}; + +static const struct perf_pmu_test_event dispatch_blocked_any = { + .event = { + .name = "dispatch_blocked.any", + .event = "umask=0x20,period=200000,event=0x9", + .desc = "Memory cluster signals to block micro-op dispatch for any reason", + .topic = "other", }, - { - .event = { - .name = "eist_trans", - .event = "umask=0x0,period=200000,event=0x3a", - .desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions", - .topic = "other", - }, - .alias_str = "umask=0,(null)=0x30d40,event=0x3a", - .alias_long_desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions", + .alias_str = "umask=0x20,(null)=0x30d40,event=0x9", + .alias_long_desc = "Memory cluster signals to block micro-op dispatch for any reason", +}; + +static const struct perf_pmu_test_event eist_trans = { + .event = { + .name = "eist_trans", + .event = "umask=0x0,period=200000,event=0x3a", + .desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions", + .topic = "other", }, - { - .event = { - .name = "l3_cache_rd", - .event = "event=0x40", - .desc = "L3 cache access, read", - .long_desc = "Attributable Level 3 cache access, read", - .topic = "cache", - }, - .alias_str = "event=0x40", - .alias_long_desc = "Attributable Level 3 cache access, read", + .alias_str = "umask=0,(null)=0x30d40,event=0x3a", + .alias_long_desc = "Number of Enhanced Intel SpeedStep(R) Technology (EIST) transitions", +}; + +static const struct perf_pmu_test_event l3_cache_rd = { + .event = { + .name = "l3_cache_rd", + .event = "event=0x40", + .desc = "L3 cache access, read", + .long_desc = "Attributable Level 3 cache access, read", + .topic = "cache", }, - { /* sentinel */ - .event = { - .name = NULL, - }, + .alias_str = "event=0x40", + .alias_long_desc = "Attributable Level 3 cache access, read", +}; + +static const struct perf_pmu_test_event *core_events[] = { + &bp_l1_btb_correct, + &bp_l2_btb_correct, + &segment_reg_loads_any, + &dispatch_blocked_any, + &eist_trans, + &l3_cache_rd, + NULL +}; + +static const struct perf_pmu_test_event uncore_hisi_ddrc_flux_wcmd = { + .event = { + .name = "uncore_hisi_ddrc.flux_wcmd", + .event = "event=0x2", + .desc = "DDRC write commands. Unit: hisi_sccl,ddrc ", + .topic = "uncore", + .long_desc = "DDRC write commands", + .pmu = "hisi_sccl,ddrc", }, + .alias_str = "event=0x2", + .alias_long_desc = "DDRC write commands", + .matching_pmu = "hisi_sccl1_ddrc2", }; -static struct perf_pmu_test_event test_uncore_events[] = { - { - .event = { - .name = "uncore_hisi_ddrc.flux_wcmd", - .event = "event=0x2", - .desc = "DDRC write commands. Unit: hisi_sccl,ddrc ", - .topic = "uncore", - .long_desc = "DDRC write commands", - .pmu = "hisi_sccl,ddrc", - }, - .alias_str = "event=0x2", - .alias_long_desc = "DDRC write commands", +static const struct perf_pmu_test_event unc_cbo_xsnp_response_miss_eviction = { + .event = { + .name = "unc_cbo_xsnp_response.miss_eviction", + .event = "umask=0x81,event=0x22", + .desc = "Unit: uncore_cbox A cross-core snoop resulted from L3 Eviction which misses in some processor core", + .topic = "uncore", + .long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", + .pmu = "uncore_cbox", }, - { - .event = { - .name = "unc_cbo_xsnp_response.miss_eviction", - .event = "umask=0x81,event=0x22", - .desc = "Unit: uncore_cbox A cross-core snoop resulted from L3 Eviction which misses in some processor core", - .topic = "uncore", - .long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", - .pmu = "uncore_cbox", - }, - .alias_str = "umask=0x81,event=0x22", - .alias_long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", + .alias_str = "umask=0x81,event=0x22", + .alias_long_desc = "A cross-core snoop resulted from L3 Eviction which misses in some processor core", + .matching_pmu = "uncore_cbox_0", +}; + +static const struct perf_pmu_test_event uncore_hisi_l3c_rd_hit_cpipe = { + .event = { + .name = "uncore_hisi_l3c.rd_hit_cpipe", + .event = "event=0x2", + .desc = "Total read hits. Unit: hisi_sccl,l3c ", + .topic = "uncore", + .long_desc = "Total read hits", + .pmu = "hisi_sccl,l3c", }, - { /* sentinel */ - .event = { - .name = NULL, - }, - } + .alias_str = "event=0x7", + .alias_long_desc = "Total read hits", + .matching_pmu = "hisi_sccl3_l3c7", +}; + +static const struct perf_pmu_test_event uncore_imc_free_running_cache_miss = { + .event = { + .name = "uncore_imc_free_running.cache_miss", + .event = "event=0x12", + .desc = "Total cache misses. Unit: uncore_imc_free_running ", + .topic = "uncore", + .long_desc = "Total cache misses", + .pmu = "uncore_imc_free_running", + }, + .alias_str = "event=0x12", + .alias_long_desc = "Total cache misses", + .matching_pmu = "uncore_imc_free_running_0", +}; + +static const struct perf_pmu_test_event uncore_imc_cache_hits = { + .event = { + .name = "uncore_imc.cache_hits", + .event = "event=0x34", + .desc = "Total cache hits. Unit: uncore_imc ", + .topic = "uncore", + .long_desc = "Total cache hits", + .pmu = "uncore_imc", + }, + .alias_str = "event=0x34", + .alias_long_desc = "Total cache hits", + .matching_pmu = "uncore_imc_0", +}; + +static const struct perf_pmu_test_event *uncore_events[] = { + &uncore_hisi_ddrc_flux_wcmd, + &unc_cbo_xsnp_response_miss_eviction, + &uncore_hisi_l3c_rd_hit_cpipe, + &uncore_imc_free_running_cache_miss, + &uncore_imc_cache_hits, + NULL }; -const int total_test_events_size = ARRAY_SIZE(test_uncore_events); +static const struct perf_pmu_test_event sys_ddr_pmu_write_cycles = { + .event = { + .name = "sys_ddr_pmu.write_cycles", + .event = "event=0x2b", + .desc = "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ", + .topic = "uncore", + .pmu = "uncore_sys_ddr_pmu", + .compat = "v8", + }, + .alias_str = "event=0x2b", + .alias_long_desc = "ddr write-cycles event. Unit: uncore_sys_ddr_pmu ", + .matching_pmu = "uncore_sys_ddr_pmu", +}; + +static const struct perf_pmu_test_event *sys_events[] = { + &sys_ddr_pmu_write_cycles, + NULL +}; static bool is_same(const char *reference, const char *test) { @@ -161,99 +241,207 @@ static struct pmu_events_map *__test_pmu_get_events_map(void) return NULL; } -/* Verify generated events from pmu-events.c is as expected */ +static struct pmu_event *__test_pmu_get_sys_events_table(void) +{ + struct pmu_sys_events *tables = &pmu_sys_event_tables[0]; + + for ( ; tables->name; tables++) { + if (!strcmp("pme_test_soc_sys", tables->name)) + return tables->table; + } + + return NULL; +} + +static int compare_pmu_events(struct pmu_event *e1, const struct pmu_event *e2) +{ + if (!is_same(e1->desc, e2->desc)) { + pr_debug2("testing event e1 %s: mismatched desc, %s vs %s\n", + e1->name, e1->desc, e2->desc); + return -1; + } + + if (!is_same(e1->topic, e2->topic)) { + pr_debug2("testing event e1 %s: mismatched topic, %s vs %s\n", + e1->name, e1->topic, e2->topic); + return -1; + } + + if (!is_same(e1->long_desc, e2->long_desc)) { + pr_debug2("testing event e1 %s: mismatched long_desc, %s vs %s\n", + e1->name, e1->long_desc, e2->long_desc); + return -1; + } + + if (!is_same(e1->unit, e2->unit)) { + pr_debug2("testing event e1 %s: mismatched unit, %s vs %s\n", + e1->name, e1->unit, e2->unit); + return -1; + } + + if (!is_same(e1->perpkg, e2->perpkg)) { + pr_debug2("testing event e1 %s: mismatched perpkg, %s vs %s\n", + e1->name, e1->perpkg, e2->perpkg); + return -1; + } + + if (!is_same(e1->metric_expr, e2->metric_expr)) { + pr_debug2("testing event e1 %s: mismatched metric_expr, %s vs %s\n", + e1->name, e1->metric_expr, e2->metric_expr); + return -1; + } + + if (!is_same(e1->metric_name, e2->metric_name)) { + pr_debug2("testing event e1 %s: mismatched metric_name, %s vs %s\n", + e1->name, e1->metric_name, e2->metric_name); + return -1; + } + + if (!is_same(e1->deprecated, e2->deprecated)) { + pr_debug2("testing event e1 %s: mismatched deprecated, %s vs %s\n", + e1->name, e1->deprecated, e2->deprecated); + return -1; + } + + if (!is_same(e1->pmu, e2->pmu)) { + pr_debug2("testing event e1 %s: mismatched pmu string, %s vs %s\n", + e1->name, e1->pmu, e2->pmu); + return -1; + } + + if (!is_same(e1->compat, e2->compat)) { + pr_debug2("testing event e1 %s: mismatched compat string, %s vs %s\n", + e1->name, e1->compat, e2->compat); + return -1; + } + + return 0; +} + +static int compare_alias_to_test_event(struct perf_pmu_alias *alias, + struct perf_pmu_test_event const *test_event, + char const *pmu_name) +{ + struct pmu_event const *event = &test_event->event; + + /* An alias was found, ensure everything is in order */ + if (!is_same(alias->name, event->name)) { + pr_debug("testing aliases PMU %s: mismatched name, %s vs %s\n", + pmu_name, alias->name, event->name); + return -1; + } + + if (!is_same(alias->desc, event->desc)) { + pr_debug("testing aliases PMU %s: mismatched desc, %s vs %s\n", + pmu_name, alias->desc, event->desc); + return -1; + } + + if (!is_same(alias->long_desc, test_event->alias_long_desc)) { + pr_debug("testing aliases PMU %s: mismatched long_desc, %s vs %s\n", + pmu_name, alias->long_desc, + test_event->alias_long_desc); + return -1; + } + + if (!is_same(alias->topic, event->topic)) { + pr_debug("testing aliases PMU %s: mismatched topic, %s vs %s\n", + pmu_name, alias->topic, event->topic); + return -1; + } + + if (!is_same(alias->str, test_event->alias_str)) { + pr_debug("testing aliases PMU %s: mismatched str, %s vs %s\n", + pmu_name, alias->str, test_event->alias_str); + return -1; + } + + if (!is_same(alias->long_desc, test_event->alias_long_desc)) { + pr_debug("testing aliases PMU %s: mismatched long desc, %s vs %s\n", + pmu_name, alias->str, test_event->alias_long_desc); + return -1; + } + + + if (!is_same(alias->pmu_name, test_event->event.pmu)) { + pr_debug("testing aliases PMU %s: mismatched pmu_name, %s vs %s\n", + pmu_name, alias->pmu_name, test_event->event.pmu); + return -1; + } + + return 0; +} + +/* Verify generated events from pmu-events.c are as expected */ static int test_pmu_event_table(void) { + struct pmu_event *sys_event_tables = __test_pmu_get_sys_events_table(); struct pmu_events_map *map = __test_pmu_get_events_map(); struct pmu_event *table; int map_events = 0, expected_events; - /* ignore 2x sentinels */ - expected_events = ARRAY_SIZE(test_cpu_events) + - ARRAY_SIZE(test_uncore_events) - 2; + /* ignore 3x sentinels */ + expected_events = ARRAY_SIZE(core_events) + + ARRAY_SIZE(uncore_events) + + ARRAY_SIZE(sys_events) - 3; - if (!map) + if (!map || !sys_event_tables) return -1; for (table = map->table; table->name; table++) { - struct perf_pmu_test_event *test; - struct pmu_event *te; + struct perf_pmu_test_event const **test_event_table; bool found = false; if (table->pmu) - test = &test_uncore_events[0]; + test_event_table = &uncore_events[0]; else - test = &test_cpu_events[0]; + test_event_table = &core_events[0]; - te = &test->event; + for (; *test_event_table; test_event_table++) { + struct perf_pmu_test_event const *test_event = *test_event_table; + struct pmu_event const *event = &test_event->event; - for (; te->name; test++, te = &test->event) { - if (strcmp(table->name, te->name)) + if (strcmp(table->name, event->name)) continue; found = true; map_events++; - if (!is_same(table->desc, te->desc)) { - pr_debug2("testing event table %s: mismatched desc, %s vs %s\n", - table->name, table->desc, te->desc); + if (compare_pmu_events(table, event)) return -1; - } - if (!is_same(table->topic, te->topic)) { - pr_debug2("testing event table %s: mismatched topic, %s vs %s\n", - table->name, table->topic, - te->topic); - return -1; - } + pr_debug("testing event table %s: pass\n", table->name); + } - if (!is_same(table->long_desc, te->long_desc)) { - pr_debug2("testing event table %s: mismatched long_desc, %s vs %s\n", - table->name, table->long_desc, - te->long_desc); - return -1; - } + if (!found) { + pr_err("testing event table: could not find event %s\n", + table->name); + return -1; + } + } - if (!is_same(table->unit, te->unit)) { - pr_debug2("testing event table %s: mismatched unit, %s vs %s\n", - table->name, table->unit, - te->unit); - return -1; - } + for (table = sys_event_tables; table->name; table++) { + struct perf_pmu_test_event const **test_event_table; + bool found = false; - if (!is_same(table->perpkg, te->perpkg)) { - pr_debug2("testing event table %s: mismatched perpkg, %s vs %s\n", - table->name, table->perpkg, - te->perpkg); - return -1; - } + test_event_table = &sys_events[0]; - if (!is_same(table->metric_expr, te->metric_expr)) { - pr_debug2("testing event table %s: mismatched metric_expr, %s vs %s\n", - table->name, table->metric_expr, - te->metric_expr); - return -1; - } + for (; *test_event_table; test_event_table++) { + struct perf_pmu_test_event const *test_event = *test_event_table; + struct pmu_event const *event = &test_event->event; - if (!is_same(table->metric_name, te->metric_name)) { - pr_debug2("testing event table %s: mismatched metric_name, %s vs %s\n", - table->name, table->metric_name, - te->metric_name); - return -1; - } + if (strcmp(table->name, event->name)) + continue; + found = true; + map_events++; - if (!is_same(table->deprecated, te->deprecated)) { - pr_debug2("testing event table %s: mismatched deprecated, %s vs %s\n", - table->name, table->deprecated, - te->deprecated); + if (compare_pmu_events(table, event)) return -1; - } - pr_debug("testing event table %s: pass\n", table->name); + pr_debug("testing sys event table %s: pass\n", table->name); } - if (!found) { - pr_err("testing event table: could not find event %s\n", - table->name); + pr_debug("testing event table: could not find event %s\n", + table->name); return -1; } } @@ -279,27 +467,19 @@ static struct perf_pmu_alias *find_alias(const char *test_event, struct list_hea } /* Verify aliases are as expected */ -static int __test__pmu_event_aliases(char *pmu_name, int *count) +static int __test_core_pmu_event_aliases(char *pmu_name, int *count) { - struct perf_pmu_test_event *test; - struct pmu_event *te; + struct perf_pmu_test_event const **test_event_table; struct perf_pmu *pmu; LIST_HEAD(aliases); int res = 0; - bool use_uncore_table; struct pmu_events_map *map = __test_pmu_get_events_map(); struct perf_pmu_alias *a, *tmp; if (!map) return -1; - if (is_pmu_core(pmu_name)) { - test = &test_cpu_events[0]; - use_uncore_table = false; - } else { - test = &test_uncore_events[0]; - use_uncore_table = true; - } + test_event_table = &core_events[0]; pmu = zalloc(sizeof(*pmu)); if (!pmu) @@ -309,91 +489,202 @@ static int __test__pmu_event_aliases(char *pmu_name, int *count) pmu_add_cpu_aliases_map(&aliases, pmu, map); - for (te = &test->event; te->name; test++, te = &test->event) { - struct perf_pmu_alias *alias = find_alias(te->name, &aliases); + for (; *test_event_table; test_event_table++) { + struct perf_pmu_test_event const *test_event = *test_event_table; + struct pmu_event const *event = &test_event->event; + struct perf_pmu_alias *alias = find_alias(event->name, &aliases); if (!alias) { - bool uncore_match = pmu_uncore_alias_match(pmu_name, - te->pmu); - - if (use_uncore_table && !uncore_match) { - pr_debug3("testing aliases PMU %s: skip matching alias %s\n", - pmu_name, te->name); - continue; - } - - pr_debug2("testing aliases PMU %s: no alias, alias_table->name=%s\n", - pmu_name, te->name); + pr_debug("testing aliases core PMU %s: no alias, alias_table->name=%s\n", + pmu_name, event->name); res = -1; break; } - if (!is_same(alias->desc, te->desc)) { - pr_debug2("testing aliases PMU %s: mismatched desc, %s vs %s\n", - pmu_name, alias->desc, te->desc); + if (compare_alias_to_test_event(alias, test_event, pmu_name)) { res = -1; break; } - if (!is_same(alias->long_desc, test->alias_long_desc)) { - pr_debug2("testing aliases PMU %s: mismatched long_desc, %s vs %s\n", - pmu_name, alias->long_desc, - test->alias_long_desc); - res = -1; - break; - } + (*count)++; + pr_debug2("testing aliases core PMU %s: matched event %s\n", + pmu_name, alias->name); + } - if (!is_same(alias->str, test->alias_str)) { - pr_debug2("testing aliases PMU %s: mismatched str, %s vs %s\n", - pmu_name, alias->str, test->alias_str); - res = -1; - break; + list_for_each_entry_safe(a, tmp, &aliases, list) { + list_del(&a->list); + perf_pmu_free_alias(a); + } + free(pmu); + return res; +} + +static int __test_uncore_pmu_event_aliases(struct perf_pmu_test_pmu *test_pmu) +{ + int alias_count = 0, to_match_count = 0, matched_count = 0; + struct perf_pmu_test_event const **table; + struct perf_pmu *pmu = &test_pmu->pmu; + const char *pmu_name = pmu->name; + struct perf_pmu_alias *a, *tmp, *alias; + struct pmu_events_map *map; + LIST_HEAD(aliases); + int res = 0; + + map = __test_pmu_get_events_map(); + if (!map) + return -1; + pmu_add_cpu_aliases_map(&aliases, pmu, map); + pmu_add_sys_aliases(&aliases, pmu); + + /* Count how many aliases we generated */ + list_for_each_entry(alias, &aliases, list) + alias_count++; + + /* Count how many aliases we expect from the known table */ + for (table = &test_pmu->aliases[0]; *table; table++) + to_match_count++; + + if (alias_count != to_match_count) { + pr_debug("testing aliases uncore PMU %s: mismatch expected aliases (%d) vs found (%d)\n", + pmu_name, to_match_count, alias_count); + res = -1; + goto out; + } + + list_for_each_entry(alias, &aliases, list) { + bool matched = false; + + for (table = &test_pmu->aliases[0]; *table; table++) { + struct perf_pmu_test_event const *test_event = *table; + struct pmu_event const *event = &test_event->event; + + if (!strcmp(event->name, alias->name)) { + if (compare_alias_to_test_event(alias, + test_event, + pmu_name)) { + continue; + } + matched = true; + matched_count++; + } } - if (!is_same(alias->topic, te->topic)) { - pr_debug2("testing aliases PMU %s: mismatched topic, %s vs %s\n", - pmu_name, alias->topic, te->topic); + if (matched == false) { + pr_debug("testing aliases uncore PMU %s: could not match alias %s\n", + pmu_name, alias->name); res = -1; - break; + goto out; } + } - (*count)++; - pr_debug2("testing aliases PMU %s: matched event %s\n", - pmu_name, alias->name); + if (alias_count != matched_count) { + pr_debug("testing aliases uncore PMU %s: mismatch found aliases (%d) vs matched (%d)\n", + pmu_name, matched_count, alias_count); + res = -1; } +out: list_for_each_entry_safe(a, tmp, &aliases, list) { list_del(&a->list); perf_pmu_free_alias(a); } - free(pmu); return res; } +static struct perf_pmu_test_pmu test_pmus[] = { + { + .pmu = { + .name = (char *)"hisi_sccl1_ddrc2", + .is_uncore = 1, + }, + .aliases = { + &uncore_hisi_ddrc_flux_wcmd, + }, + }, + { + .pmu = { + .name = (char *)"uncore_cbox_0", + .is_uncore = 1, + }, + .aliases = { + &unc_cbo_xsnp_response_miss_eviction, + }, + }, + { + .pmu = { + .name = (char *)"hisi_sccl3_l3c7", + .is_uncore = 1, + }, + .aliases = { + &uncore_hisi_l3c_rd_hit_cpipe, + }, + }, + { + .pmu = { + .name = (char *)"uncore_imc_free_running_0", + .is_uncore = 1, + }, + .aliases = { + &uncore_imc_free_running_cache_miss, + }, + }, + { + .pmu = { + .name = (char *)"uncore_imc_0", + .is_uncore = 1, + }, + .aliases = { + &uncore_imc_cache_hits, + }, + }, + { + .pmu = { + .name = (char *)"uncore_sys_ddr_pmu0", + .is_uncore = 1, + .id = (char *)"v8", + }, + .aliases = { + &sys_ddr_pmu_write_cycles, + }, + }, +}; /* Test that aliases generated are as expected */ static int test_aliases(void) { struct perf_pmu *pmu = NULL; + unsigned long i; while ((pmu = perf_pmu__scan(pmu)) != NULL) { int count = 0; + if (!is_pmu_core(pmu->name)) + continue; + if (list_empty(&pmu->format)) { - pr_debug2("skipping testing PMU %s\n", pmu->name); + pr_debug2("skipping testing core PMU %s\n", pmu->name); continue; } - if (__test__pmu_event_aliases(pmu->name, &count)) { - pr_debug("testing PMU %s aliases: failed\n", pmu->name); + if (__test_core_pmu_event_aliases(pmu->name, &count)) { + pr_debug("testing core PMU %s aliases: failed\n", pmu->name); return -1; } - if (count == 0) - pr_debug3("testing PMU %s aliases: no events to match\n", + if (count == 0) { + pr_debug("testing core PMU %s aliases: no events to match\n", pmu->name); - else - pr_debug("testing PMU %s aliases: pass\n", pmu->name); + return -1; + } + + pr_debug("testing core PMU %s aliases: pass\n", pmu->name); + } + + for (i = 0; i < ARRAY_SIZE(test_pmus); i++) { + int res = __test_uncore_pmu_event_aliases(&test_pmus[i]); + + if (res) + return res; } return 0; diff --git a/tools/perf/tests/shell/lib/probe_vfs_getname.sh b/tools/perf/tests/shell/lib/probe_vfs_getname.sh index c2cc42daf924..5b17d916c555 100644 --- a/tools/perf/tests/shell/lib/probe_vfs_getname.sh +++ b/tools/perf/tests/shell/lib/probe_vfs_getname.sh @@ -19,6 +19,6 @@ add_probe_vfs_getname() { } skip_if_no_debuginfo() { - add_probe_vfs_getname -v 2>&1 | egrep -q "^(Failed to find the path for kernel|Debuginfo-analysis is not supported)" && return 2 + add_probe_vfs_getname -v 2>&1 | egrep -q "^(Failed to find the path for the kernel|Debuginfo-analysis is not supported)" && return 2 return 1 } diff --git a/tools/perf/tests/shell/pipe_test.sh b/tools/perf/tests/shell/pipe_test.sh new file mode 100755 index 000000000000..1b32b4f28391 --- /dev/null +++ b/tools/perf/tests/shell/pipe_test.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# perf pipe recording and injection test +# SPDX-License-Identifier: GPL-2.0 + +# skip if there's no compiler +if ! [ -x "$(command -v cc)" ]; then + echo "failed: no compiler, install gcc" + exit 2 +fi + +file=$(mktemp /tmp/test.file.XXXXXX) +data=$(mktemp /tmp/perf.data.XXXXXX) + +cat <<EOF | cc -o ${file} -x c - +#include <signal.h> +#include <stdlib.h> +#include <unistd.h> + +volatile int done; + +void sigalrm(int sig) { + done = 1; +} + +__attribute__((noinline)) void noploop(void) { + while (!done) + continue; +} + +int main(int argc, char *argv[]) { + int sec = 1; + + if (argc > 1) + sec = atoi(argv[1]); + + signal(SIGALRM, sigalrm); + alarm(sec); + + noploop(); + return 0; +} +EOF + + +if ! perf record -e task-clock:u -o - ${file} | perf report -i - --task | grep test.file; then + echo "cannot find the test file in the perf report" + exit 1 +fi + +if ! perf record -e task-clock:u -o - ${file} | perf inject -b | perf report -i - | grep noploop; then + echo "cannot find noploop function in pipe #1" + exit 1 +fi + +perf record -e task-clock:u -o - ${file} | perf inject -b -o ${data} +if ! perf report -i ${data} | grep noploop; then + echo "cannot find noploop function in pipe #2" + exit 1 +fi + +perf record -e task-clock:u -o ${data} ${file} +if ! perf inject -b -i ${data} | perf report -i - | grep noploop; then + echo "cannot find noploop function in pipe #3" + exit 1 +fi + + +rm -f ${file} ${data} ${data}.old +exit 0 diff --git a/tools/perf/tests/shell/record+zstd_comp_decomp.sh b/tools/perf/tests/shell/record+zstd_comp_decomp.sh index 045723b3d992..8a168cf8bacc 100755 --- a/tools/perf/tests/shell/record+zstd_comp_decomp.sh +++ b/tools/perf/tests/shell/record+zstd_comp_decomp.sh @@ -25,8 +25,8 @@ check_compressed_stats() { check_compressed_output() { $perf_tool inject -i $trace_file -o $trace_file.decomp && - $perf_tool report -i $trace_file --stdio | head -n -3 > $trace_file.comp.output && - $perf_tool report -i $trace_file.decomp --stdio | head -n -3 > $trace_file.decomp.output && + $perf_tool report -i $trace_file --stdio -F comm,dso,sym | head -n -3 > $trace_file.comp.output && + $perf_tool report -i $trace_file.decomp --stdio -F comm,dso,sym | head -n -3 > $trace_file.decomp.output && diff $trace_file.comp.output $trace_file.decomp.output } diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h index 1100dd55b657..fe1306f58495 100644 --- a/tools/perf/tests/tests.h +++ b/tools/perf/tests/tests.h @@ -127,6 +127,7 @@ int test__parse_metric(struct test *test, int subtest); int test__pe_file_parsing(struct test *test, int subtest); int test__expand_cgroup_events(struct test *test, int subtest); int test__perf_time_to_tsc(struct test *test, int subtest); +int test__dlfilter(struct test *test, int subtest); bool test__bp_signal_is_supported(void); bool test__bp_account_is_supported(void); diff --git a/tools/perf/tests/topology.c b/tools/perf/tests/topology.c index b5efe675b321..b9028e304ddd 100644 --- a/tools/perf/tests/topology.c +++ b/tools/perf/tests/topology.c @@ -38,7 +38,7 @@ static int session_write_header(char *path) .mode = PERF_DATA_MODE_WRITE, }; - session = perf_session__new(&data, false, NULL); + session = perf_session__new(&data, NULL); TEST_ASSERT_VAL("can't get session", !IS_ERR(session)); if (!perf_pmu__has_hybrid()) { @@ -77,7 +77,7 @@ static int check_cpu_topology(char *path, struct perf_cpu_map *map) int i; struct aggr_cpu_id id; - session = perf_session__new(&data, false, NULL); + session = perf_session__new(&data, NULL); TEST_ASSERT_VAL("can't get session", !IS_ERR(session)); cpu__setup_cpunode_map(); |