* [PATCH 1/2] perf trace-event-info: Rename for_each_event. @ 2021-02-03 5:26 Ian Rogers 2021-02-03 5:26 ` [PATCH 2/2] perf parse-events: Break out tracepoint and printing Ian Rogers 0 siblings, 1 reply; 8+ messages in thread From: Ian Rogers @ 2021-02-03 5:26 UTC (permalink / raw) To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim, linux-kernel Cc: Stephane Eranian, Ian Rogers Avoid a naming conflict with for_each_event with similar code in parse-events.c, rename to for_each_event_tps. Signed-off-by: Ian Rogers <irogers@google.com> --- tools/perf/util/trace-event-info.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index 0e5c4786f296..a65f65d0857e 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -152,7 +152,7 @@ static bool name_in_tp_list(char *sys, struct tracepoint_path *tps) return false; } -#define for_each_event(dir, dent, tps) \ +#define for_each_event_tps(dir, dent, tps) \ while ((dent = readdir(dir))) \ if (dent->d_type == DT_DIR && \ (strcmp(dent->d_name, ".")) && \ @@ -174,7 +174,7 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps) return -errno; } - for_each_event(dir, dent, tps) { + for_each_event_tps(dir, dent, tps) { if (!name_in_tp_list(dent->d_name, tps)) continue; @@ -196,7 +196,7 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps) } rewinddir(dir); - for_each_event(dir, dent, tps) { + for_each_event_tps(dir, dent, tps) { if (!name_in_tp_list(dent->d_name, tps)) continue; @@ -274,7 +274,7 @@ static int record_event_files(struct tracepoint_path *tps) goto out; } - for_each_event(dir, dent, tps) { + for_each_event_tps(dir, dent, tps) { if (strcmp(dent->d_name, "ftrace") == 0 || !system_in_tp_list(dent->d_name, tps)) continue; @@ -289,7 +289,7 @@ static int record_event_files(struct tracepoint_path *tps) } rewinddir(dir); - for_each_event(dir, dent, tps) { + for_each_event_tps(dir, dent, tps) { if (strcmp(dent->d_name, "ftrace") == 0 || !system_in_tp_list(dent->d_name, tps)) continue; -- 2.30.0.365.g02bc693789-goog ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2] perf parse-events: Break out tracepoint and printing. 2021-02-03 5:26 [PATCH 1/2] perf trace-event-info: Rename for_each_event Ian Rogers @ 2021-02-03 5:26 ` Ian Rogers 2021-02-03 16:20 ` Arnaldo Carvalho de Melo 0 siblings, 1 reply; 8+ messages in thread From: Ian Rogers @ 2021-02-03 5:26 UTC (permalink / raw) To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo, Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim, linux-kernel Cc: Stephane Eranian, Ian Rogers Move print_*_events functions out of parse-events.c into a new print-events.c. Move tracepoint code into tracepoint.c or trace-event-info.c (sole user). This reduces the dependencies of parse-events.c and makes it more amenable to being a library in the future. Remove some unnecessary definitions from parse-events.h. Fix a checkpatch.pl warning on using unsigned rather than unsigned int. Signed-off-by: Ian Rogers <irogers@google.com> --- tools/perf/builtin-list.c | 2 +- tools/perf/builtin-lock.c | 1 + tools/perf/builtin-timechart.c | 1 + tools/perf/builtin-trace.c | 1 + tools/perf/util/Build | 2 + tools/perf/util/parse-events.c | 620 +---------------------------- tools/perf/util/parse-events.h | 29 -- tools/perf/util/print-events.c | 472 ++++++++++++++++++++++ tools/perf/util/print-events.h | 21 + tools/perf/util/trace-event-info.c | 94 +++++ tools/perf/util/tracepoint.c | 63 +++ tools/perf/util/tracepoint.h | 25 ++ 12 files changed, 687 insertions(+), 644 deletions(-) create mode 100644 tools/perf/util/print-events.c create mode 100644 tools/perf/util/print-events.h create mode 100644 tools/perf/util/tracepoint.c create mode 100644 tools/perf/util/tracepoint.h diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index 10ab5e40a34f..91327a321c36 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -10,7 +10,7 @@ */ #include "builtin.h" -#include "util/parse-events.h" +#include "util/print-events.h" #include "util/pmu.h" #include "util/debug.h" #include "util/metricgroup.h" diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index a2f1e53f37a7..486123cb106e 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -13,6 +13,7 @@ #include <subcmd/pager.h> #include <subcmd/parse-options.h> #include "util/trace-event.h" +#include "util/tracepoint.h" #include "util/debug.h" #include "util/session.h" diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c index 4e380e7b5230..cdebcf26f408 100644 --- a/tools/perf/builtin-timechart.c +++ b/tools/perf/builtin-timechart.c @@ -35,6 +35,7 @@ #include "util/tool.h" #include "util/data.h" #include "util/debug.h" +#include "util/tracepoint.h" #include <linux/err.h> #ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 85b6a46e85b6..b3b9fa1c7731 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c @@ -53,6 +53,7 @@ #include "trace-event.h" #include "util/parse-events.h" #include "util/bpf-loader.h" +#include "util/tracepoint.h" #include "callchain.h" #include "print_binary.h" #include "string2.h" diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 188521f34347..c2c9f3f490e8 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build @@ -23,6 +23,8 @@ perf-y += llvm-utils.o perf-y += mmap.o perf-y += memswap.o perf-y += parse-events.o +perf-y += print-events.o +perf-y += tracepoint.o perf-y += perf_regs.o perf-y += path.o perf-y += print_binary.o diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 42c84adeb2fb..5d5ebb700ef2 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -5,42 +5,34 @@ #include <dirent.h> #include <errno.h> #include <sys/ioctl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> #include <sys/param.h> #include "term.h" -#include "build-id.h" #include "evlist.h" #include "evsel.h" -#include <subcmd/pager.h> #include <subcmd/parse-options.h> #include "parse-events.h" -#include <subcmd/exec-cmd.h> #include "string2.h" -#include "strlist.h" -#include "symbol.h" -#include "header.h" #include "bpf-loader.h" #include "debug.h" #include <api/fs/tracing_path.h> #include <perf/cpumap.h> #include "parse-events-bison.h" -#define YY_EXTRA_TYPE void* #include "parse-events-flex.h" #include "pmu.h" -#include "thread_map.h" -#include "probe-file.h" #include "asm/bug.h" #include "util/parse-branch-options.h" -#include "metricgroup.h" #include "util/evsel_config.h" #include "util/event.h" -#include "util/pfm.h" #include "perf.h" +#include "tracepoint.h" #define MAX_NAME_LEN 100 +struct perf_pmu_event_symbol { + char *symbol; + enum perf_pmu_event_symbol_type type; +}; + #ifdef PARSER_DEBUG extern int parse_events_debug; #endif @@ -155,35 +147,6 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) -#define for_each_subsystem(sys_dir, sys_dirent) \ - while ((sys_dirent = readdir(sys_dir)) != NULL) \ - if (sys_dirent->d_type == DT_DIR && \ - (strcmp(sys_dirent->d_name, ".")) && \ - (strcmp(sys_dirent->d_name, ".."))) - -static int tp_event_has_id(const char *dir_path, struct dirent *evt_dir) -{ - char evt_path[MAXPATHLEN]; - int fd; - - snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, evt_dir->d_name); - fd = open(evt_path, O_RDONLY); - if (fd < 0) - return -EINVAL; - close(fd); - - return 0; -} - -#define for_each_event(dir_path, evt_dir, evt_dirent) \ - while ((evt_dirent = readdir(evt_dir)) != NULL) \ - if (evt_dirent->d_type == DT_DIR && \ - (strcmp(evt_dirent->d_name, ".")) && \ - (strcmp(evt_dirent->d_name, "..")) && \ - (!tp_event_has_id(dir_path, evt_dirent))) - -#define MAX_EVENT_LENGTH 512 - void parse_events__handle_error(struct parse_events_error *err, int idx, char *str, char *help) { @@ -217,92 +180,6 @@ void parse_events__handle_error(struct parse_events_error *err, int idx, err->num_errors++; } -struct tracepoint_path *tracepoint_id_to_path(u64 config) -{ - struct tracepoint_path *path = NULL; - DIR *sys_dir, *evt_dir; - struct dirent *sys_dirent, *evt_dirent; - char id_buf[24]; - int fd; - u64 id; - char evt_path[MAXPATHLEN]; - char *dir_path; - - sys_dir = tracing_events__opendir(); - if (!sys_dir) - return NULL; - - for_each_subsystem(sys_dir, sys_dirent) { - dir_path = get_events_file(sys_dirent->d_name); - if (!dir_path) - continue; - evt_dir = opendir(dir_path); - if (!evt_dir) - goto next; - - for_each_event(dir_path, evt_dir, evt_dirent) { - - scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, - evt_dirent->d_name); - fd = open(evt_path, O_RDONLY); - if (fd < 0) - continue; - if (read(fd, id_buf, sizeof(id_buf)) < 0) { - close(fd); - continue; - } - close(fd); - id = atoll(id_buf); - if (id == config) { - put_events_file(dir_path); - closedir(evt_dir); - closedir(sys_dir); - path = zalloc(sizeof(*path)); - if (!path) - return NULL; - if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { - free(path); - return NULL; - } - if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { - zfree(&path->system); - free(path); - return NULL; - } - return path; - } - } - closedir(evt_dir); -next: - put_events_file(dir_path); - } - - closedir(sys_dir); - return NULL; -} - -struct tracepoint_path *tracepoint_name_to_path(const char *name) -{ - struct tracepoint_path *path = zalloc(sizeof(*path)); - char *str = strchr(name, ':'); - - if (path == NULL || str == NULL) { - free(path); - return NULL; - } - - path->system = strndup(name, str - name); - path->name = strdup(str+1); - - if (path->system == NULL || path->name == NULL) { - zfree(&path->system); - zfree(&path->name); - zfree(&path); - } - - return path; -} - const char *event_type(int type) { switch (type) { @@ -2451,491 +2328,6 @@ int exclude_perf(const struct option *opt, NULL); } -static const char * const event_type_descriptors[] = { - "Hardware event", - "Software event", - "Tracepoint event", - "Hardware cache event", - "Raw hardware event descriptor", - "Hardware breakpoint", -}; - -static int cmp_string(const void *a, const void *b) -{ - const char * const *as = a; - const char * const *bs = b; - - return strcmp(*as, *bs); -} - -/* - * Print the events from <debugfs_mount_point>/tracing/events - */ - -void print_tracepoint_events(const char *subsys_glob, const char *event_glob, - bool name_only) -{ - DIR *sys_dir, *evt_dir; - struct dirent *sys_dirent, *evt_dirent; - char evt_path[MAXPATHLEN]; - char *dir_path; - char **evt_list = NULL; - unsigned int evt_i = 0, evt_num = 0; - bool evt_num_known = false; - -restart: - sys_dir = tracing_events__opendir(); - if (!sys_dir) - return; - - if (evt_num_known) { - evt_list = zalloc(sizeof(char *) * evt_num); - if (!evt_list) - goto out_close_sys_dir; - } - - for_each_subsystem(sys_dir, sys_dirent) { - if (subsys_glob != NULL && - !strglobmatch(sys_dirent->d_name, subsys_glob)) - continue; - - dir_path = get_events_file(sys_dirent->d_name); - if (!dir_path) - continue; - evt_dir = opendir(dir_path); - if (!evt_dir) - goto next; - - for_each_event(dir_path, evt_dir, evt_dirent) { - if (event_glob != NULL && - !strglobmatch(evt_dirent->d_name, event_glob)) - continue; - - if (!evt_num_known) { - evt_num++; - continue; - } - - snprintf(evt_path, MAXPATHLEN, "%s:%s", - sys_dirent->d_name, evt_dirent->d_name); - - evt_list[evt_i] = strdup(evt_path); - if (evt_list[evt_i] == NULL) { - put_events_file(dir_path); - goto out_close_evt_dir; - } - evt_i++; - } - closedir(evt_dir); -next: - put_events_file(dir_path); - } - closedir(sys_dir); - - if (!evt_num_known) { - evt_num_known = true; - goto restart; - } - qsort(evt_list, evt_num, sizeof(char *), cmp_string); - evt_i = 0; - while (evt_i < evt_num) { - if (name_only) { - printf("%s ", evt_list[evt_i++]); - continue; - } - printf(" %-50s [%s]\n", evt_list[evt_i++], - event_type_descriptors[PERF_TYPE_TRACEPOINT]); - } - if (evt_num && pager_in_use()) - printf("\n"); - -out_free: - evt_num = evt_i; - for (evt_i = 0; evt_i < evt_num; evt_i++) - zfree(&evt_list[evt_i]); - zfree(&evt_list); - return; - -out_close_evt_dir: - closedir(evt_dir); -out_close_sys_dir: - closedir(sys_dir); - - printf("FATAL: not enough memory to print %s\n", - event_type_descriptors[PERF_TYPE_TRACEPOINT]); - if (evt_list) - goto out_free; -} - -/* - * Check whether event is in <debugfs_mount_point>/tracing/events - */ - -int is_valid_tracepoint(const char *event_string) -{ - DIR *sys_dir, *evt_dir; - struct dirent *sys_dirent, *evt_dirent; - char evt_path[MAXPATHLEN]; - char *dir_path; - - sys_dir = tracing_events__opendir(); - if (!sys_dir) - return 0; - - for_each_subsystem(sys_dir, sys_dirent) { - dir_path = get_events_file(sys_dirent->d_name); - if (!dir_path) - continue; - evt_dir = opendir(dir_path); - if (!evt_dir) - goto next; - - for_each_event(dir_path, evt_dir, evt_dirent) { - snprintf(evt_path, MAXPATHLEN, "%s:%s", - sys_dirent->d_name, evt_dirent->d_name); - if (!strcmp(evt_path, event_string)) { - closedir(evt_dir); - closedir(sys_dir); - return 1; - } - } - closedir(evt_dir); -next: - put_events_file(dir_path); - } - closedir(sys_dir); - return 0; -} - -static bool is_event_supported(u8 type, unsigned config) -{ - bool ret = true; - int open_return; - struct evsel *evsel; - struct perf_event_attr attr = { - .type = type, - .config = config, - .disabled = 1, - }; - struct perf_thread_map *tmap = thread_map__new_by_tid(0); - - if (tmap == NULL) - return false; - - evsel = evsel__new(&attr); - if (evsel) { - open_return = evsel__open(evsel, NULL, tmap); - ret = open_return >= 0; - - if (open_return == -EACCES) { - /* - * This happens if the paranoid value - * /proc/sys/kernel/perf_event_paranoid is set to 2 - * Re-run with exclude_kernel set; we don't do that - * by default as some ARM machines do not support it. - * - */ - evsel->core.attr.exclude_kernel = 1; - ret = evsel__open(evsel, NULL, tmap) >= 0; - } - evsel__delete(evsel); - } - - perf_thread_map__put(tmap); - return ret; -} - -void print_sdt_events(const char *subsys_glob, const char *event_glob, - bool name_only) -{ - struct probe_cache *pcache; - struct probe_cache_entry *ent; - struct strlist *bidlist, *sdtlist; - struct strlist_config cfg = {.dont_dupstr = true}; - struct str_node *nd, *nd2; - char *buf, *path, *ptr = NULL; - bool show_detail = false; - int ret; - - sdtlist = strlist__new(NULL, &cfg); - if (!sdtlist) { - pr_debug("Failed to allocate new strlist for SDT\n"); - return; - } - bidlist = build_id_cache__list_all(true); - if (!bidlist) { - pr_debug("Failed to get buildids: %d\n", errno); - return; - } - strlist__for_each_entry(nd, bidlist) { - pcache = probe_cache__new(nd->s, NULL); - if (!pcache) - continue; - list_for_each_entry(ent, &pcache->entries, node) { - if (!ent->sdt) - continue; - if (subsys_glob && - !strglobmatch(ent->pev.group, subsys_glob)) - continue; - if (event_glob && - !strglobmatch(ent->pev.event, event_glob)) - continue; - ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, - ent->pev.event, nd->s); - if (ret > 0) - strlist__add(sdtlist, buf); - } - probe_cache__delete(pcache); - } - strlist__delete(bidlist); - - strlist__for_each_entry(nd, sdtlist) { - buf = strchr(nd->s, '@'); - if (buf) - *(buf++) = '\0'; - if (name_only) { - printf("%s ", nd->s); - continue; - } - nd2 = strlist__next(nd); - if (nd2) { - ptr = strchr(nd2->s, '@'); - if (ptr) - *ptr = '\0'; - if (strcmp(nd->s, nd2->s) == 0) - show_detail = true; - } - if (show_detail) { - path = build_id_cache__origname(buf); - ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf); - if (ret > 0) { - printf(" %-50s [%s]\n", buf, "SDT event"); - free(buf); - } - free(path); - } else - printf(" %-50s [%s]\n", nd->s, "SDT event"); - if (nd2) { - if (strcmp(nd->s, nd2->s) != 0) - show_detail = false; - if (ptr) - *ptr = '@'; - } - } - strlist__delete(sdtlist); -} - -int print_hwcache_events(const char *event_glob, bool name_only) -{ - unsigned int type, op, i, evt_i = 0, evt_num = 0; - char name[64]; - char **evt_list = NULL; - bool evt_num_known = false; - -restart: - if (evt_num_known) { - evt_list = zalloc(sizeof(char *) * evt_num); - if (!evt_list) - goto out_enomem; - } - - for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { - for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { - /* skip invalid cache type */ - if (!evsel__is_cache_op_valid(type, op)) - continue; - - for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { - __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); - if (event_glob != NULL && !strglobmatch(name, event_glob)) - continue; - - if (!is_event_supported(PERF_TYPE_HW_CACHE, - type | (op << 8) | (i << 16))) - continue; - - if (!evt_num_known) { - evt_num++; - continue; - } - - evt_list[evt_i] = strdup(name); - if (evt_list[evt_i] == NULL) - goto out_enomem; - evt_i++; - } - } - } - - if (!evt_num_known) { - evt_num_known = true; - goto restart; - } - qsort(evt_list, evt_num, sizeof(char *), cmp_string); - evt_i = 0; - while (evt_i < evt_num) { - if (name_only) { - printf("%s ", evt_list[evt_i++]); - continue; - } - printf(" %-50s [%s]\n", evt_list[evt_i++], - event_type_descriptors[PERF_TYPE_HW_CACHE]); - } - if (evt_num && pager_in_use()) - printf("\n"); - -out_free: - evt_num = evt_i; - for (evt_i = 0; evt_i < evt_num; evt_i++) - zfree(&evt_list[evt_i]); - zfree(&evt_list); - return evt_num; - -out_enomem: - printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]); - if (evt_list) - goto out_free; - return evt_num; -} - -static void print_tool_event(const char *name, const char *event_glob, - bool name_only) -{ - if (event_glob && !strglobmatch(name, event_glob)) - return; - if (name_only) - printf("%s ", name); - else - printf(" %-50s [%s]\n", name, "Tool event"); - -} - -void print_tool_events(const char *event_glob, bool name_only) -{ - print_tool_event("duration_time", event_glob, name_only); - if (pager_in_use()) - printf("\n"); -} - -void print_symbol_events(const char *event_glob, unsigned type, - struct event_symbol *syms, unsigned max, - bool name_only) -{ - unsigned int i, evt_i = 0, evt_num = 0; - char name[MAX_NAME_LEN]; - char **evt_list = NULL; - bool evt_num_known = false; - -restart: - if (evt_num_known) { - evt_list = zalloc(sizeof(char *) * evt_num); - if (!evt_list) - goto out_enomem; - syms -= max; - } - - for (i = 0; i < max; i++, syms++) { - - if (event_glob != NULL && syms->symbol != NULL && - !(strglobmatch(syms->symbol, event_glob) || - (syms->alias && strglobmatch(syms->alias, event_glob)))) - continue; - - if (!is_event_supported(type, i)) - continue; - - if (!evt_num_known) { - evt_num++; - continue; - } - - if (!name_only && strlen(syms->alias)) - snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); - else - strlcpy(name, syms->symbol, MAX_NAME_LEN); - - evt_list[evt_i] = strdup(name); - if (evt_list[evt_i] == NULL) - goto out_enomem; - evt_i++; - } - - if (!evt_num_known) { - evt_num_known = true; - goto restart; - } - qsort(evt_list, evt_num, sizeof(char *), cmp_string); - evt_i = 0; - while (evt_i < evt_num) { - if (name_only) { - printf("%s ", evt_list[evt_i++]); - continue; - } - printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); - } - if (evt_num && pager_in_use()) - printf("\n"); - -out_free: - evt_num = evt_i; - for (evt_i = 0; evt_i < evt_num; evt_i++) - zfree(&evt_list[evt_i]); - zfree(&evt_list); - return; - -out_enomem: - printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); - if (evt_list) - goto out_free; -} - -/* - * Print the help text for the event symbols: - */ -void print_events(const char *event_glob, bool name_only, bool quiet_flag, - bool long_desc, bool details_flag, bool deprecated) -{ - print_symbol_events(event_glob, PERF_TYPE_HARDWARE, - event_symbols_hw, PERF_COUNT_HW_MAX, name_only); - - print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, - event_symbols_sw, PERF_COUNT_SW_MAX, name_only); - print_tool_events(event_glob, name_only); - - print_hwcache_events(event_glob, name_only); - - print_pmu_events(event_glob, name_only, quiet_flag, long_desc, - details_flag, deprecated); - - if (event_glob != NULL) - return; - - if (!name_only) { - printf(" %-50s [%s]\n", - "rNNN", - event_type_descriptors[PERF_TYPE_RAW]); - printf(" %-50s [%s]\n", - "cpu/t1=v1[,t2=v2,t3 ...]/modifier", - event_type_descriptors[PERF_TYPE_RAW]); - if (pager_in_use()) - printf(" (see 'man perf-list' on how to encode it)\n\n"); - - printf(" %-50s [%s]\n", - "mem:<addr>[/len][:access]", - event_type_descriptors[PERF_TYPE_BREAKPOINT]); - if (pager_in_use()) - printf("\n"); - } - - print_tracepoint_events(NULL, NULL, name_only); - - print_sdt_events(NULL, NULL, name_only); - - metricgroup__print(true, true, NULL, name_only, details_flag); - - print_libpfm_events(name_only, long_desc); -} - int parse_events__is_hardcoded_term(struct parse_events_term *term) { return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index e80c9b74f2f2..7cea425e80f9 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h @@ -11,7 +11,6 @@ #include <linux/perf_event.h> #include <string.h> -struct list_head; struct evsel; struct evlist; struct parse_events_error; @@ -19,14 +18,6 @@ struct parse_events_error; struct option; struct perf_pmu; -struct tracepoint_path { - char *system; - char *name; - struct tracepoint_path *next; -}; - -struct tracepoint_path *tracepoint_id_to_path(u64 config); -struct tracepoint_path *tracepoint_name_to_path(const char *name); bool have_tracepoints(struct list_head *evlist); const char *event_type(int type); @@ -46,8 +37,6 @@ int parse_events_terms(struct list_head *terms, const char *str); int parse_filter(const struct option *opt, const char *str, int unset); int exclude_perf(const struct option *opt, const char *arg, int unset); -#define EVENTS_HELP_MAX (128*1024) - enum perf_pmu_event_symbol_type { PMU_EVENT_SYMBOL_ERR, /* not a PMU EVENT */ PMU_EVENT_SYMBOL, /* normal style PMU event */ @@ -55,11 +44,6 @@ enum perf_pmu_event_symbol_type { PMU_EVENT_SYMBOL_SUFFIX, /* suffix of pre-suf style event */ }; -struct perf_pmu_event_symbol { - char *symbol; - enum perf_pmu_event_symbol_type type; -}; - enum { PARSE_EVENTS__TERM_TYPE_NUM, PARSE_EVENTS__TERM_TYPE_STR, @@ -216,8 +200,6 @@ void parse_events_update_lists(struct list_head *list_event, void parse_events_evlist_error(struct parse_events_state *parse_state, int idx, const char *str); -void print_events(const char *event_glob, bool name_only, bool quiet, - bool long_desc, bool details_flag, bool deprecated); struct event_symbol { const char *symbol; @@ -225,18 +207,7 @@ struct event_symbol { }; extern struct event_symbol event_symbols_hw[]; extern struct event_symbol event_symbols_sw[]; -void print_symbol_events(const char *event_glob, unsigned type, - struct event_symbol *syms, unsigned max, - bool name_only); -void print_tool_events(const char *event_glob, bool name_only); -void print_tracepoint_events(const char *subsys_glob, const char *event_glob, - bool name_only); -int print_hwcache_events(const char *event_glob, bool name_only); -void print_sdt_events(const char *subsys_glob, const char *event_glob, - bool name_only); -int is_valid_tracepoint(const char *event_string); -int valid_event_mount(const char *eventfs); char *parse_events_formats_error_string(char *additional_terms); void parse_events_print_error(struct parse_events_error *err, diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c new file mode 100644 index 000000000000..584888353d13 --- /dev/null +++ b/tools/perf/util/print-events.c @@ -0,0 +1,472 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <dirent.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/param.h> + +#include <api/fs/tracing_path.h> +#include <linux/perf_event.h> +#include <linux/zalloc.h> +#include <subcmd/pager.h> + +#include "build-id.h" +#include "debug.h" +#include "evsel.h" +#include "metricgroup.h" +#include "parse-events.h" +#include "pmu.h" +#include "print-events.h" +#include "probe-file.h" +#include "string2.h" +#include "strlist.h" +#include "thread_map.h" +#include "tracepoint.h" +#include "pfm.h" + +#define MAX_NAME_LEN 100 + +static int cmp_string(const void *a, const void *b) +{ + const char * const *as = a; + const char * const *bs = b; + + return strcmp(*as, *bs); +} + +static const char * const event_type_descriptors[] = { + "Hardware event", + "Software event", + "Tracepoint event", + "Hardware cache event", + "Raw hardware event descriptor", + "Hardware breakpoint", +}; + +/* + * Print the events from <debugfs_mount_point>/tracing/events + */ +void print_tracepoint_events(const char *subsys_glob, + const char *event_glob, bool name_only) +{ + DIR *sys_dir, *evt_dir; + struct dirent *sys_dirent, *evt_dirent; + char evt_path[MAXPATHLEN]; + char *dir_path; + char **evt_list = NULL; + unsigned int evt_i = 0, evt_num = 0; + bool evt_num_known = false; + +restart: + sys_dir = tracing_events__opendir(); + if (!sys_dir) + return; + + if (evt_num_known) { + evt_list = zalloc(sizeof(char *) * evt_num); + if (!evt_list) + goto out_close_sys_dir; + } + + for_each_subsystem(sys_dir, sys_dirent) { + if (subsys_glob != NULL && + !strglobmatch(sys_dirent->d_name, subsys_glob)) + continue; + + dir_path = get_events_file(sys_dirent->d_name); + if (!dir_path) + continue; + evt_dir = opendir(dir_path); + if (!evt_dir) + goto next; + + for_each_event(dir_path, evt_dir, evt_dirent) { + if (event_glob != NULL && + !strglobmatch(evt_dirent->d_name, event_glob)) + continue; + + if (!evt_num_known) { + evt_num++; + continue; + } + + snprintf(evt_path, MAXPATHLEN, "%s:%s", + sys_dirent->d_name, evt_dirent->d_name); + + evt_list[evt_i] = strdup(evt_path); + if (evt_list[evt_i] == NULL) { + put_events_file(dir_path); + goto out_close_evt_dir; + } + evt_i++; + } + closedir(evt_dir); +next: + put_events_file(dir_path); + } + closedir(sys_dir); + + if (!evt_num_known) { + evt_num_known = true; + goto restart; + } + qsort(evt_list, evt_num, sizeof(char *), cmp_string); + evt_i = 0; + while (evt_i < evt_num) { + if (name_only) { + printf("%s ", evt_list[evt_i++]); + continue; + } + printf(" %-50s [%s]\n", evt_list[evt_i++], + event_type_descriptors[PERF_TYPE_TRACEPOINT]); + } + if (evt_num && pager_in_use()) + printf("\n"); + +out_free: + evt_num = evt_i; + for (evt_i = 0; evt_i < evt_num; evt_i++) + zfree(&evt_list[evt_i]); + zfree(&evt_list); + return; + +out_close_evt_dir: + closedir(evt_dir); +out_close_sys_dir: + closedir(sys_dir); + + printf("FATAL: not enough memory to print %s\n", + event_type_descriptors[PERF_TYPE_TRACEPOINT]); + if (evt_list) + goto out_free; +} + +void print_sdt_events(const char *subsys_glob, const char *event_glob, + bool name_only) +{ + struct probe_cache *pcache; + struct probe_cache_entry *ent; + struct strlist *bidlist, *sdtlist; + struct strlist_config cfg = {.dont_dupstr = true}; + struct str_node *nd, *nd2; + char *buf, *path, *ptr = NULL; + bool show_detail = false; + int ret; + + sdtlist = strlist__new(NULL, &cfg); + if (!sdtlist) { + pr_debug("Failed to allocate new strlist for SDT\n"); + return; + } + bidlist = build_id_cache__list_all(true); + if (!bidlist) { + pr_debug("Failed to get buildids: %d\n", errno); + return; + } + strlist__for_each_entry(nd, bidlist) { + pcache = probe_cache__new(nd->s, NULL); + if (!pcache) + continue; + list_for_each_entry(ent, &pcache->entries, node) { + if (!ent->sdt) + continue; + if (subsys_glob && + !strglobmatch(ent->pev.group, subsys_glob)) + continue; + if (event_glob && + !strglobmatch(ent->pev.event, event_glob)) + continue; + ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, + ent->pev.event, nd->s); + if (ret > 0) + strlist__add(sdtlist, buf); + } + probe_cache__delete(pcache); + } + strlist__delete(bidlist); + + strlist__for_each_entry(nd, sdtlist) { + buf = strchr(nd->s, '@'); + if (buf) + *(buf++) = '\0'; + if (name_only) { + printf("%s ", nd->s); + continue; + } + nd2 = strlist__next(nd); + if (nd2) { + ptr = strchr(nd2->s, '@'); + if (ptr) + *ptr = '\0'; + if (strcmp(nd->s, nd2->s) == 0) + show_detail = true; + } + if (show_detail) { + path = build_id_cache__origname(buf); + ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf); + if (ret > 0) { + printf(" %-50s [%s]\n", buf, "SDT event"); + free(buf); + } + free(path); + } else + printf(" %-50s [%s]\n", nd->s, "SDT event"); + if (nd2) { + if (strcmp(nd->s, nd2->s) != 0) + show_detail = false; + if (ptr) + *ptr = '@'; + } + } + strlist__delete(sdtlist); +} + +static bool is_event_supported(u8 type, unsigned int config) +{ + bool ret = true; + int open_return; + struct evsel *evsel; + struct perf_event_attr attr = { + .type = type, + .config = config, + .disabled = 1, + }; + struct perf_thread_map *tmap = thread_map__new_by_tid(0); + + if (tmap == NULL) + return false; + + evsel = evsel__new(&attr); + if (evsel) { + open_return = evsel__open(evsel, NULL, tmap); + ret = open_return >= 0; + + if (open_return == -EACCES) { + /* + * This happens if the paranoid value + * /proc/sys/kernel/perf_event_paranoid is set to 2 + * Re-run with exclude_kernel set; we don't do that + * by default as some ARM machines do not support it. + * + */ + evsel->core.attr.exclude_kernel = 1; + ret = evsel__open(evsel, NULL, tmap) >= 0; + } + evsel__delete(evsel); + } + + perf_thread_map__put(tmap); + return ret; +} + +int print_hwcache_events(const char *event_glob, bool name_only) +{ + unsigned int type, op, i, evt_i = 0, evt_num = 0; + char name[64]; + char **evt_list = NULL; + bool evt_num_known = false; + +restart: + if (evt_num_known) { + evt_list = zalloc(sizeof(char *) * evt_num); + if (!evt_list) + goto out_enomem; + } + + for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { + for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { + /* skip invalid cache type */ + if (!evsel__is_cache_op_valid(type, op)) + continue; + + for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { + __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); + if (event_glob != NULL && !strglobmatch(name, event_glob)) + continue; + + if (!is_event_supported(PERF_TYPE_HW_CACHE, + type | (op << 8) | (i << 16))) + continue; + + if (!evt_num_known) { + evt_num++; + continue; + } + + evt_list[evt_i] = strdup(name); + if (evt_list[evt_i] == NULL) + goto out_enomem; + evt_i++; + } + } + } + + if (!evt_num_known) { + evt_num_known = true; + goto restart; + } + qsort(evt_list, evt_num, sizeof(char *), cmp_string); + evt_i = 0; + while (evt_i < evt_num) { + if (name_only) { + printf("%s ", evt_list[evt_i++]); + continue; + } + printf(" %-50s [%s]\n", evt_list[evt_i++], + event_type_descriptors[PERF_TYPE_HW_CACHE]); + } + if (evt_num && pager_in_use()) + printf("\n"); + +out_free: + evt_num = evt_i; + for (evt_i = 0; evt_i < evt_num; evt_i++) + zfree(&evt_list[evt_i]); + zfree(&evt_list); + return evt_num; + +out_enomem: + printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]); + if (evt_list) + goto out_free; + return evt_num; +} + +static void print_tool_event(const char *name, const char *event_glob, + bool name_only) +{ + if (event_glob && !strglobmatch(name, event_glob)) + return; + if (name_only) + printf("%s ", name); + else + printf(" %-50s [%s]\n", name, "Tool event"); + +} + +void print_tool_events(const char *event_glob, bool name_only) +{ + print_tool_event("duration_time", event_glob, name_only); + if (pager_in_use()) + printf("\n"); +} + +void print_symbol_events(const char *event_glob, unsigned int type, + struct event_symbol *syms, unsigned int max, + bool name_only) +{ + unsigned int i, evt_i = 0, evt_num = 0; + char name[MAX_NAME_LEN]; + char **evt_list = NULL; + bool evt_num_known = false; + +restart: + if (evt_num_known) { + evt_list = zalloc(sizeof(char *) * evt_num); + if (!evt_list) + goto out_enomem; + syms -= max; + } + + for (i = 0; i < max; i++, syms++) { + + if (event_glob != NULL && syms->symbol != NULL && + !(strglobmatch(syms->symbol, event_glob) || + (syms->alias && strglobmatch(syms->alias, event_glob)))) + continue; + + if (!is_event_supported(type, i)) + continue; + + if (!evt_num_known) { + evt_num++; + continue; + } + + if (!name_only && strlen(syms->alias)) + snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); + else + strlcpy(name, syms->symbol, MAX_NAME_LEN); + + evt_list[evt_i] = strdup(name); + if (evt_list[evt_i] == NULL) + goto out_enomem; + evt_i++; + } + + if (!evt_num_known) { + evt_num_known = true; + goto restart; + } + qsort(evt_list, evt_num, sizeof(char *), cmp_string); + evt_i = 0; + while (evt_i < evt_num) { + if (name_only) { + printf("%s ", evt_list[evt_i++]); + continue; + } + printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); + } + if (evt_num && pager_in_use()) + printf("\n"); + +out_free: + evt_num = evt_i; + for (evt_i = 0; evt_i < evt_num; evt_i++) + zfree(&evt_list[evt_i]); + zfree(&evt_list); + return; + +out_enomem: + printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); + if (evt_list) + goto out_free; +} + +/* + * Print the help text for the event symbols: + */ +void print_events(const char *event_glob, bool name_only, bool quiet_flag, + bool long_desc, bool details_flag, bool deprecated) +{ + print_symbol_events(event_glob, PERF_TYPE_HARDWARE, + event_symbols_hw, PERF_COUNT_HW_MAX, name_only); + + print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, + event_symbols_sw, PERF_COUNT_SW_MAX, name_only); + print_tool_events(event_glob, name_only); + + print_hwcache_events(event_glob, name_only); + + print_pmu_events(event_glob, name_only, quiet_flag, long_desc, + details_flag, deprecated); + + if (event_glob != NULL) + return; + + if (!name_only) { + printf(" %-50s [%s]\n", + "rNNN", + event_type_descriptors[PERF_TYPE_RAW]); + printf(" %-50s [%s]\n", + "cpu/t1=v1[,t2=v2,t3 ...]/modifier", + event_type_descriptors[PERF_TYPE_RAW]); + if (pager_in_use()) + printf(" (see 'man perf-list' on how to encode it)\n\n"); + + printf(" %-50s [%s]\n", + "mem:<addr>[/len][:access]", + event_type_descriptors[PERF_TYPE_BREAKPOINT]); + if (pager_in_use()) + printf("\n"); + } + + print_tracepoint_events(NULL, NULL, name_only); + + print_sdt_events(NULL, NULL, name_only); + + metricgroup__print(true, true, NULL, name_only, details_flag); + + print_libpfm_events(name_only, long_desc); +} diff --git a/tools/perf/util/print-events.h b/tools/perf/util/print-events.h new file mode 100644 index 000000000000..cf64e8129c1b --- /dev/null +++ b/tools/perf/util/print-events.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_PRINT_EVENTS_H +#define __PERF_PRINT_EVENTS_H + +#include <stdbool.h> + +struct event_symbol; + +void print_events(const char *event_glob, bool name_only, bool quiet, + bool long_desc, bool details_flag, bool deprecated); +int print_hwcache_events(const char *event_glob, bool name_only); +void print_sdt_events(const char *subsys_glob, const char *event_glob, + bool name_only); +void print_symbol_events(const char *event_glob, unsigned int type, + struct event_symbol *syms, unsigned int max, + bool name_only); +void print_tool_events(const char *event_glob, bool name_only); +void print_tracepoint_events(const char *subsys_glob, const char *event_glob, + bool name_only); + +#endif /* __PERF_PRINT_EVENTS_H */ diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index a65f65d0857e..fbc6d14aabbb 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c @@ -19,16 +19,24 @@ #include <linux/kernel.h> #include <linux/zalloc.h> #include <internal/lib.h> // page_size +#include <sys/param.h> #include "trace-event.h" +#include "tracepoint.h" #include <api/fs/tracing_path.h> #include "evsel.h" #include "debug.h" #define VERSION "0.6" +#define MAX_EVENT_LENGTH 512 static int output_fd; +struct tracepoint_path { + char *system; + char *name; + struct tracepoint_path *next; +}; int bigendian(void) { @@ -400,6 +408,92 @@ put_tracepoints_path(struct tracepoint_path *tps) } } +static struct tracepoint_path *tracepoint_id_to_path(u64 config) +{ + struct tracepoint_path *path = NULL; + DIR *sys_dir, *evt_dir; + struct dirent *sys_dirent, *evt_dirent; + char id_buf[24]; + int fd; + u64 id; + char evt_path[MAXPATHLEN]; + char *dir_path; + + sys_dir = tracing_events__opendir(); + if (!sys_dir) + return NULL; + + for_each_subsystem(sys_dir, sys_dirent) { + dir_path = get_events_file(sys_dirent->d_name); + if (!dir_path) + continue; + evt_dir = opendir(dir_path); + if (!evt_dir) + goto next; + + for_each_event(dir_path, evt_dir, evt_dirent) { + + scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, + evt_dirent->d_name); + fd = open(evt_path, O_RDONLY); + if (fd < 0) + continue; + if (read(fd, id_buf, sizeof(id_buf)) < 0) { + close(fd); + continue; + } + close(fd); + id = atoll(id_buf); + if (id == config) { + put_events_file(dir_path); + closedir(evt_dir); + closedir(sys_dir); + path = zalloc(sizeof(*path)); + if (!path) + return NULL; + if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { + free(path); + return NULL; + } + if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { + zfree(&path->system); + free(path); + return NULL; + } + return path; + } + } + closedir(evt_dir); +next: + put_events_file(dir_path); + } + + closedir(sys_dir); + return NULL; +} + +static struct tracepoint_path *tracepoint_name_to_path(const char *name) +{ + struct tracepoint_path *path = zalloc(sizeof(*path)); + char *str = strchr(name, ':'); + + if (path == NULL || str == NULL) { + free(path); + return NULL; + } + + path->system = strndup(name, str - name); + path->name = strdup(str+1); + + if (path->system == NULL || path->name == NULL) { + zfree(&path->system); + zfree(&path->name); + zfree(&path); + } + + return path; +} + static struct tracepoint_path * get_tracepoints_path(struct list_head *pattrs) { diff --git a/tools/perf/util/tracepoint.c b/tools/perf/util/tracepoint.c new file mode 100644 index 000000000000..89ef56c43311 --- /dev/null +++ b/tools/perf/util/tracepoint.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +#include "tracepoint.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <sys/param.h> +#include <unistd.h> + +#include <api/fs/tracing_path.h> + +int tp_event_has_id(const char *dir_path, struct dirent *evt_dir) +{ + char evt_path[MAXPATHLEN]; + int fd; + + snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, evt_dir->d_name); + fd = open(evt_path, O_RDONLY); + if (fd < 0) + return -EINVAL; + close(fd); + + return 0; +} + +/* + * Check whether event is in <debugfs_mount_point>/tracing/events + */ +int is_valid_tracepoint(const char *event_string) +{ + DIR *sys_dir, *evt_dir; + struct dirent *sys_dirent, *evt_dirent; + char evt_path[MAXPATHLEN]; + char *dir_path; + + sys_dir = tracing_events__opendir(); + if (!sys_dir) + return 0; + + for_each_subsystem(sys_dir, sys_dirent) { + dir_path = get_events_file(sys_dirent->d_name); + if (!dir_path) + continue; + evt_dir = opendir(dir_path); + if (!evt_dir) + goto next; + + for_each_event(dir_path, evt_dir, evt_dirent) { + snprintf(evt_path, MAXPATHLEN, "%s:%s", + sys_dirent->d_name, evt_dirent->d_name); + if (!strcmp(evt_path, event_string)) { + closedir(evt_dir); + closedir(sys_dir); + return 1; + } + } + closedir(evt_dir); +next: + put_events_file(dir_path); + } + closedir(sys_dir); + return 0; +} diff --git a/tools/perf/util/tracepoint.h b/tools/perf/util/tracepoint.h new file mode 100644 index 000000000000..c4a110fe87d7 --- /dev/null +++ b/tools/perf/util/tracepoint.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __PERF_TRACEPOINT_H +#define __PERF_TRACEPOINT_H + +#include <dirent.h> +#include <string.h> + +int tp_event_has_id(const char *dir_path, struct dirent *evt_dir); + +#define for_each_event(dir_path, evt_dir, evt_dirent) \ + while ((evt_dirent = readdir(evt_dir)) != NULL) \ + if (evt_dirent->d_type == DT_DIR && \ + (strcmp(evt_dirent->d_name, ".")) && \ + (strcmp(evt_dirent->d_name, "..")) && \ + (!tp_event_has_id(dir_path, evt_dirent))) + +#define for_each_subsystem(sys_dir, sys_dirent) \ + while ((sys_dirent = readdir(sys_dir)) != NULL) \ + if (sys_dirent->d_type == DT_DIR && \ + (strcmp(sys_dirent->d_name, ".")) && \ + (strcmp(sys_dirent->d_name, ".."))) + +int is_valid_tracepoint(const char *event_string); + +#endif /* __PERF_TRACEPOINT_H */ -- 2.30.0.365.g02bc693789-goog ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] perf parse-events: Break out tracepoint and printing. 2021-02-03 5:26 ` [PATCH 2/2] perf parse-events: Break out tracepoint and printing Ian Rogers @ 2021-02-03 16:20 ` Arnaldo Carvalho de Melo 2021-02-03 19:02 ` Ian Rogers [not found] ` <CAP-5=fVFeT6YtXJGHX0OC1BCa121bTC+ER7XDVO2g5rr8DYfDw@mail.gmail.com> 0 siblings, 2 replies; 8+ messages in thread From: Arnaldo Carvalho de Melo @ 2021-02-03 16:20 UTC (permalink / raw) To: Ian Rogers Cc: Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim, linux-kernel, Stephane Eranian Em Tue, Feb 02, 2021 at 09:26:59PM -0800, Ian Rogers escreveu: > Move print_*_events functions out of parse-events.c into a new > print-events.c. Move tracepoint code into tracepoint.c or > trace-event-info.c (sole user). This reduces the dependencies of > parse-events.c and makes it more amenable to being a library in the > future. > Remove some unnecessary definitions from parse-events.h. Fix a > checkpatch.pl warning on using unsigned rather than unsigned int. Thanks, applied. - Arnaldo > Signed-off-by: Ian Rogers <irogers@google.com> > --- > tools/perf/builtin-list.c | 2 +- > tools/perf/builtin-lock.c | 1 + > tools/perf/builtin-timechart.c | 1 + > tools/perf/builtin-trace.c | 1 + > tools/perf/util/Build | 2 + > tools/perf/util/parse-events.c | 620 +---------------------------- > tools/perf/util/parse-events.h | 29 -- > tools/perf/util/print-events.c | 472 ++++++++++++++++++++++ > tools/perf/util/print-events.h | 21 + > tools/perf/util/trace-event-info.c | 94 +++++ > tools/perf/util/tracepoint.c | 63 +++ > tools/perf/util/tracepoint.h | 25 ++ > 12 files changed, 687 insertions(+), 644 deletions(-) > create mode 100644 tools/perf/util/print-events.c > create mode 100644 tools/perf/util/print-events.h > create mode 100644 tools/perf/util/tracepoint.c > create mode 100644 tools/perf/util/tracepoint.h > > diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c > index 10ab5e40a34f..91327a321c36 100644 > --- a/tools/perf/builtin-list.c > +++ b/tools/perf/builtin-list.c > @@ -10,7 +10,7 @@ > */ > #include "builtin.h" > > -#include "util/parse-events.h" > +#include "util/print-events.h" > #include "util/pmu.h" > #include "util/debug.h" > #include "util/metricgroup.h" > diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c > index a2f1e53f37a7..486123cb106e 100644 > --- a/tools/perf/builtin-lock.c > +++ b/tools/perf/builtin-lock.c > @@ -13,6 +13,7 @@ > #include <subcmd/pager.h> > #include <subcmd/parse-options.h> > #include "util/trace-event.h" > +#include "util/tracepoint.h" > > #include "util/debug.h" > #include "util/session.h" > diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c > index 4e380e7b5230..cdebcf26f408 100644 > --- a/tools/perf/builtin-timechart.c > +++ b/tools/perf/builtin-timechart.c > @@ -35,6 +35,7 @@ > #include "util/tool.h" > #include "util/data.h" > #include "util/debug.h" > +#include "util/tracepoint.h" > #include <linux/err.h> > > #ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE > diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c > index 85b6a46e85b6..b3b9fa1c7731 100644 > --- a/tools/perf/builtin-trace.c > +++ b/tools/perf/builtin-trace.c > @@ -53,6 +53,7 @@ > #include "trace-event.h" > #include "util/parse-events.h" > #include "util/bpf-loader.h" > +#include "util/tracepoint.h" > #include "callchain.h" > #include "print_binary.h" > #include "string2.h" > diff --git a/tools/perf/util/Build b/tools/perf/util/Build > index 188521f34347..c2c9f3f490e8 100644 > --- a/tools/perf/util/Build > +++ b/tools/perf/util/Build > @@ -23,6 +23,8 @@ perf-y += llvm-utils.o > perf-y += mmap.o > perf-y += memswap.o > perf-y += parse-events.o > +perf-y += print-events.o > +perf-y += tracepoint.o > perf-y += perf_regs.o > perf-y += path.o > perf-y += print_binary.o > diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c > index 42c84adeb2fb..5d5ebb700ef2 100644 > --- a/tools/perf/util/parse-events.c > +++ b/tools/perf/util/parse-events.c > @@ -5,42 +5,34 @@ > #include <dirent.h> > #include <errno.h> > #include <sys/ioctl.h> > -#include <sys/types.h> > -#include <sys/stat.h> > -#include <fcntl.h> > #include <sys/param.h> > #include "term.h" > -#include "build-id.h" > #include "evlist.h" > #include "evsel.h" > -#include <subcmd/pager.h> > #include <subcmd/parse-options.h> > #include "parse-events.h" > -#include <subcmd/exec-cmd.h> > #include "string2.h" > -#include "strlist.h" > -#include "symbol.h" > -#include "header.h" > #include "bpf-loader.h" > #include "debug.h" > #include <api/fs/tracing_path.h> > #include <perf/cpumap.h> > #include "parse-events-bison.h" > -#define YY_EXTRA_TYPE void* > #include "parse-events-flex.h" > #include "pmu.h" > -#include "thread_map.h" > -#include "probe-file.h" > #include "asm/bug.h" > #include "util/parse-branch-options.h" > -#include "metricgroup.h" > #include "util/evsel_config.h" > #include "util/event.h" > -#include "util/pfm.h" > #include "perf.h" > +#include "tracepoint.h" > > #define MAX_NAME_LEN 100 > > +struct perf_pmu_event_symbol { > + char *symbol; > + enum perf_pmu_event_symbol_type type; > +}; > + > #ifdef PARSER_DEBUG > extern int parse_events_debug; > #endif > @@ -155,35 +147,6 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { > #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) > #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) > > -#define for_each_subsystem(sys_dir, sys_dirent) \ > - while ((sys_dirent = readdir(sys_dir)) != NULL) \ > - if (sys_dirent->d_type == DT_DIR && \ > - (strcmp(sys_dirent->d_name, ".")) && \ > - (strcmp(sys_dirent->d_name, ".."))) > - > -static int tp_event_has_id(const char *dir_path, struct dirent *evt_dir) > -{ > - char evt_path[MAXPATHLEN]; > - int fd; > - > - snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, evt_dir->d_name); > - fd = open(evt_path, O_RDONLY); > - if (fd < 0) > - return -EINVAL; > - close(fd); > - > - return 0; > -} > - > -#define for_each_event(dir_path, evt_dir, evt_dirent) \ > - while ((evt_dirent = readdir(evt_dir)) != NULL) \ > - if (evt_dirent->d_type == DT_DIR && \ > - (strcmp(evt_dirent->d_name, ".")) && \ > - (strcmp(evt_dirent->d_name, "..")) && \ > - (!tp_event_has_id(dir_path, evt_dirent))) > - > -#define MAX_EVENT_LENGTH 512 > - > void parse_events__handle_error(struct parse_events_error *err, int idx, > char *str, char *help) > { > @@ -217,92 +180,6 @@ void parse_events__handle_error(struct parse_events_error *err, int idx, > err->num_errors++; > } > > -struct tracepoint_path *tracepoint_id_to_path(u64 config) > -{ > - struct tracepoint_path *path = NULL; > - DIR *sys_dir, *evt_dir; > - struct dirent *sys_dirent, *evt_dirent; > - char id_buf[24]; > - int fd; > - u64 id; > - char evt_path[MAXPATHLEN]; > - char *dir_path; > - > - sys_dir = tracing_events__opendir(); > - if (!sys_dir) > - return NULL; > - > - for_each_subsystem(sys_dir, sys_dirent) { > - dir_path = get_events_file(sys_dirent->d_name); > - if (!dir_path) > - continue; > - evt_dir = opendir(dir_path); > - if (!evt_dir) > - goto next; > - > - for_each_event(dir_path, evt_dir, evt_dirent) { > - > - scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, > - evt_dirent->d_name); > - fd = open(evt_path, O_RDONLY); > - if (fd < 0) > - continue; > - if (read(fd, id_buf, sizeof(id_buf)) < 0) { > - close(fd); > - continue; > - } > - close(fd); > - id = atoll(id_buf); > - if (id == config) { > - put_events_file(dir_path); > - closedir(evt_dir); > - closedir(sys_dir); > - path = zalloc(sizeof(*path)); > - if (!path) > - return NULL; > - if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { > - free(path); > - return NULL; > - } > - if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { > - zfree(&path->system); > - free(path); > - return NULL; > - } > - return path; > - } > - } > - closedir(evt_dir); > -next: > - put_events_file(dir_path); > - } > - > - closedir(sys_dir); > - return NULL; > -} > - > -struct tracepoint_path *tracepoint_name_to_path(const char *name) > -{ > - struct tracepoint_path *path = zalloc(sizeof(*path)); > - char *str = strchr(name, ':'); > - > - if (path == NULL || str == NULL) { > - free(path); > - return NULL; > - } > - > - path->system = strndup(name, str - name); > - path->name = strdup(str+1); > - > - if (path->system == NULL || path->name == NULL) { > - zfree(&path->system); > - zfree(&path->name); > - zfree(&path); > - } > - > - return path; > -} > - > const char *event_type(int type) > { > switch (type) { > @@ -2451,491 +2328,6 @@ int exclude_perf(const struct option *opt, > NULL); > } > > -static const char * const event_type_descriptors[] = { > - "Hardware event", > - "Software event", > - "Tracepoint event", > - "Hardware cache event", > - "Raw hardware event descriptor", > - "Hardware breakpoint", > -}; > - > -static int cmp_string(const void *a, const void *b) > -{ > - const char * const *as = a; > - const char * const *bs = b; > - > - return strcmp(*as, *bs); > -} > - > -/* > - * Print the events from <debugfs_mount_point>/tracing/events > - */ > - > -void print_tracepoint_events(const char *subsys_glob, const char *event_glob, > - bool name_only) > -{ > - DIR *sys_dir, *evt_dir; > - struct dirent *sys_dirent, *evt_dirent; > - char evt_path[MAXPATHLEN]; > - char *dir_path; > - char **evt_list = NULL; > - unsigned int evt_i = 0, evt_num = 0; > - bool evt_num_known = false; > - > -restart: > - sys_dir = tracing_events__opendir(); > - if (!sys_dir) > - return; > - > - if (evt_num_known) { > - evt_list = zalloc(sizeof(char *) * evt_num); > - if (!evt_list) > - goto out_close_sys_dir; > - } > - > - for_each_subsystem(sys_dir, sys_dirent) { > - if (subsys_glob != NULL && > - !strglobmatch(sys_dirent->d_name, subsys_glob)) > - continue; > - > - dir_path = get_events_file(sys_dirent->d_name); > - if (!dir_path) > - continue; > - evt_dir = opendir(dir_path); > - if (!evt_dir) > - goto next; > - > - for_each_event(dir_path, evt_dir, evt_dirent) { > - if (event_glob != NULL && > - !strglobmatch(evt_dirent->d_name, event_glob)) > - continue; > - > - if (!evt_num_known) { > - evt_num++; > - continue; > - } > - > - snprintf(evt_path, MAXPATHLEN, "%s:%s", > - sys_dirent->d_name, evt_dirent->d_name); > - > - evt_list[evt_i] = strdup(evt_path); > - if (evt_list[evt_i] == NULL) { > - put_events_file(dir_path); > - goto out_close_evt_dir; > - } > - evt_i++; > - } > - closedir(evt_dir); > -next: > - put_events_file(dir_path); > - } > - closedir(sys_dir); > - > - if (!evt_num_known) { > - evt_num_known = true; > - goto restart; > - } > - qsort(evt_list, evt_num, sizeof(char *), cmp_string); > - evt_i = 0; > - while (evt_i < evt_num) { > - if (name_only) { > - printf("%s ", evt_list[evt_i++]); > - continue; > - } > - printf(" %-50s [%s]\n", evt_list[evt_i++], > - event_type_descriptors[PERF_TYPE_TRACEPOINT]); > - } > - if (evt_num && pager_in_use()) > - printf("\n"); > - > -out_free: > - evt_num = evt_i; > - for (evt_i = 0; evt_i < evt_num; evt_i++) > - zfree(&evt_list[evt_i]); > - zfree(&evt_list); > - return; > - > -out_close_evt_dir: > - closedir(evt_dir); > -out_close_sys_dir: > - closedir(sys_dir); > - > - printf("FATAL: not enough memory to print %s\n", > - event_type_descriptors[PERF_TYPE_TRACEPOINT]); > - if (evt_list) > - goto out_free; > -} > - > -/* > - * Check whether event is in <debugfs_mount_point>/tracing/events > - */ > - > -int is_valid_tracepoint(const char *event_string) > -{ > - DIR *sys_dir, *evt_dir; > - struct dirent *sys_dirent, *evt_dirent; > - char evt_path[MAXPATHLEN]; > - char *dir_path; > - > - sys_dir = tracing_events__opendir(); > - if (!sys_dir) > - return 0; > - > - for_each_subsystem(sys_dir, sys_dirent) { > - dir_path = get_events_file(sys_dirent->d_name); > - if (!dir_path) > - continue; > - evt_dir = opendir(dir_path); > - if (!evt_dir) > - goto next; > - > - for_each_event(dir_path, evt_dir, evt_dirent) { > - snprintf(evt_path, MAXPATHLEN, "%s:%s", > - sys_dirent->d_name, evt_dirent->d_name); > - if (!strcmp(evt_path, event_string)) { > - closedir(evt_dir); > - closedir(sys_dir); > - return 1; > - } > - } > - closedir(evt_dir); > -next: > - put_events_file(dir_path); > - } > - closedir(sys_dir); > - return 0; > -} > - > -static bool is_event_supported(u8 type, unsigned config) > -{ > - bool ret = true; > - int open_return; > - struct evsel *evsel; > - struct perf_event_attr attr = { > - .type = type, > - .config = config, > - .disabled = 1, > - }; > - struct perf_thread_map *tmap = thread_map__new_by_tid(0); > - > - if (tmap == NULL) > - return false; > - > - evsel = evsel__new(&attr); > - if (evsel) { > - open_return = evsel__open(evsel, NULL, tmap); > - ret = open_return >= 0; > - > - if (open_return == -EACCES) { > - /* > - * This happens if the paranoid value > - * /proc/sys/kernel/perf_event_paranoid is set to 2 > - * Re-run with exclude_kernel set; we don't do that > - * by default as some ARM machines do not support it. > - * > - */ > - evsel->core.attr.exclude_kernel = 1; > - ret = evsel__open(evsel, NULL, tmap) >= 0; > - } > - evsel__delete(evsel); > - } > - > - perf_thread_map__put(tmap); > - return ret; > -} > - > -void print_sdt_events(const char *subsys_glob, const char *event_glob, > - bool name_only) > -{ > - struct probe_cache *pcache; > - struct probe_cache_entry *ent; > - struct strlist *bidlist, *sdtlist; > - struct strlist_config cfg = {.dont_dupstr = true}; > - struct str_node *nd, *nd2; > - char *buf, *path, *ptr = NULL; > - bool show_detail = false; > - int ret; > - > - sdtlist = strlist__new(NULL, &cfg); > - if (!sdtlist) { > - pr_debug("Failed to allocate new strlist for SDT\n"); > - return; > - } > - bidlist = build_id_cache__list_all(true); > - if (!bidlist) { > - pr_debug("Failed to get buildids: %d\n", errno); > - return; > - } > - strlist__for_each_entry(nd, bidlist) { > - pcache = probe_cache__new(nd->s, NULL); > - if (!pcache) > - continue; > - list_for_each_entry(ent, &pcache->entries, node) { > - if (!ent->sdt) > - continue; > - if (subsys_glob && > - !strglobmatch(ent->pev.group, subsys_glob)) > - continue; > - if (event_glob && > - !strglobmatch(ent->pev.event, event_glob)) > - continue; > - ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, > - ent->pev.event, nd->s); > - if (ret > 0) > - strlist__add(sdtlist, buf); > - } > - probe_cache__delete(pcache); > - } > - strlist__delete(bidlist); > - > - strlist__for_each_entry(nd, sdtlist) { > - buf = strchr(nd->s, '@'); > - if (buf) > - *(buf++) = '\0'; > - if (name_only) { > - printf("%s ", nd->s); > - continue; > - } > - nd2 = strlist__next(nd); > - if (nd2) { > - ptr = strchr(nd2->s, '@'); > - if (ptr) > - *ptr = '\0'; > - if (strcmp(nd->s, nd2->s) == 0) > - show_detail = true; > - } > - if (show_detail) { > - path = build_id_cache__origname(buf); > - ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf); > - if (ret > 0) { > - printf(" %-50s [%s]\n", buf, "SDT event"); > - free(buf); > - } > - free(path); > - } else > - printf(" %-50s [%s]\n", nd->s, "SDT event"); > - if (nd2) { > - if (strcmp(nd->s, nd2->s) != 0) > - show_detail = false; > - if (ptr) > - *ptr = '@'; > - } > - } > - strlist__delete(sdtlist); > -} > - > -int print_hwcache_events(const char *event_glob, bool name_only) > -{ > - unsigned int type, op, i, evt_i = 0, evt_num = 0; > - char name[64]; > - char **evt_list = NULL; > - bool evt_num_known = false; > - > -restart: > - if (evt_num_known) { > - evt_list = zalloc(sizeof(char *) * evt_num); > - if (!evt_list) > - goto out_enomem; > - } > - > - for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { > - for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { > - /* skip invalid cache type */ > - if (!evsel__is_cache_op_valid(type, op)) > - continue; > - > - for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { > - __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); > - if (event_glob != NULL && !strglobmatch(name, event_glob)) > - continue; > - > - if (!is_event_supported(PERF_TYPE_HW_CACHE, > - type | (op << 8) | (i << 16))) > - continue; > - > - if (!evt_num_known) { > - evt_num++; > - continue; > - } > - > - evt_list[evt_i] = strdup(name); > - if (evt_list[evt_i] == NULL) > - goto out_enomem; > - evt_i++; > - } > - } > - } > - > - if (!evt_num_known) { > - evt_num_known = true; > - goto restart; > - } > - qsort(evt_list, evt_num, sizeof(char *), cmp_string); > - evt_i = 0; > - while (evt_i < evt_num) { > - if (name_only) { > - printf("%s ", evt_list[evt_i++]); > - continue; > - } > - printf(" %-50s [%s]\n", evt_list[evt_i++], > - event_type_descriptors[PERF_TYPE_HW_CACHE]); > - } > - if (evt_num && pager_in_use()) > - printf("\n"); > - > -out_free: > - evt_num = evt_i; > - for (evt_i = 0; evt_i < evt_num; evt_i++) > - zfree(&evt_list[evt_i]); > - zfree(&evt_list); > - return evt_num; > - > -out_enomem: > - printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]); > - if (evt_list) > - goto out_free; > - return evt_num; > -} > - > -static void print_tool_event(const char *name, const char *event_glob, > - bool name_only) > -{ > - if (event_glob && !strglobmatch(name, event_glob)) > - return; > - if (name_only) > - printf("%s ", name); > - else > - printf(" %-50s [%s]\n", name, "Tool event"); > - > -} > - > -void print_tool_events(const char *event_glob, bool name_only) > -{ > - print_tool_event("duration_time", event_glob, name_only); > - if (pager_in_use()) > - printf("\n"); > -} > - > -void print_symbol_events(const char *event_glob, unsigned type, > - struct event_symbol *syms, unsigned max, > - bool name_only) > -{ > - unsigned int i, evt_i = 0, evt_num = 0; > - char name[MAX_NAME_LEN]; > - char **evt_list = NULL; > - bool evt_num_known = false; > - > -restart: > - if (evt_num_known) { > - evt_list = zalloc(sizeof(char *) * evt_num); > - if (!evt_list) > - goto out_enomem; > - syms -= max; > - } > - > - for (i = 0; i < max; i++, syms++) { > - > - if (event_glob != NULL && syms->symbol != NULL && > - !(strglobmatch(syms->symbol, event_glob) || > - (syms->alias && strglobmatch(syms->alias, event_glob)))) > - continue; > - > - if (!is_event_supported(type, i)) > - continue; > - > - if (!evt_num_known) { > - evt_num++; > - continue; > - } > - > - if (!name_only && strlen(syms->alias)) > - snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); > - else > - strlcpy(name, syms->symbol, MAX_NAME_LEN); > - > - evt_list[evt_i] = strdup(name); > - if (evt_list[evt_i] == NULL) > - goto out_enomem; > - evt_i++; > - } > - > - if (!evt_num_known) { > - evt_num_known = true; > - goto restart; > - } > - qsort(evt_list, evt_num, sizeof(char *), cmp_string); > - evt_i = 0; > - while (evt_i < evt_num) { > - if (name_only) { > - printf("%s ", evt_list[evt_i++]); > - continue; > - } > - printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); > - } > - if (evt_num && pager_in_use()) > - printf("\n"); > - > -out_free: > - evt_num = evt_i; > - for (evt_i = 0; evt_i < evt_num; evt_i++) > - zfree(&evt_list[evt_i]); > - zfree(&evt_list); > - return; > - > -out_enomem: > - printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); > - if (evt_list) > - goto out_free; > -} > - > -/* > - * Print the help text for the event symbols: > - */ > -void print_events(const char *event_glob, bool name_only, bool quiet_flag, > - bool long_desc, bool details_flag, bool deprecated) > -{ > - print_symbol_events(event_glob, PERF_TYPE_HARDWARE, > - event_symbols_hw, PERF_COUNT_HW_MAX, name_only); > - > - print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, > - event_symbols_sw, PERF_COUNT_SW_MAX, name_only); > - print_tool_events(event_glob, name_only); > - > - print_hwcache_events(event_glob, name_only); > - > - print_pmu_events(event_glob, name_only, quiet_flag, long_desc, > - details_flag, deprecated); > - > - if (event_glob != NULL) > - return; > - > - if (!name_only) { > - printf(" %-50s [%s]\n", > - "rNNN", > - event_type_descriptors[PERF_TYPE_RAW]); > - printf(" %-50s [%s]\n", > - "cpu/t1=v1[,t2=v2,t3 ...]/modifier", > - event_type_descriptors[PERF_TYPE_RAW]); > - if (pager_in_use()) > - printf(" (see 'man perf-list' on how to encode it)\n\n"); > - > - printf(" %-50s [%s]\n", > - "mem:<addr>[/len][:access]", > - event_type_descriptors[PERF_TYPE_BREAKPOINT]); > - if (pager_in_use()) > - printf("\n"); > - } > - > - print_tracepoint_events(NULL, NULL, name_only); > - > - print_sdt_events(NULL, NULL, name_only); > - > - metricgroup__print(true, true, NULL, name_only, details_flag); > - > - print_libpfm_events(name_only, long_desc); > -} > - > int parse_events__is_hardcoded_term(struct parse_events_term *term) > { > return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; > diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h > index e80c9b74f2f2..7cea425e80f9 100644 > --- a/tools/perf/util/parse-events.h > +++ b/tools/perf/util/parse-events.h > @@ -11,7 +11,6 @@ > #include <linux/perf_event.h> > #include <string.h> > > -struct list_head; > struct evsel; > struct evlist; > struct parse_events_error; > @@ -19,14 +18,6 @@ struct parse_events_error; > struct option; > struct perf_pmu; > > -struct tracepoint_path { > - char *system; > - char *name; > - struct tracepoint_path *next; > -}; > - > -struct tracepoint_path *tracepoint_id_to_path(u64 config); > -struct tracepoint_path *tracepoint_name_to_path(const char *name); > bool have_tracepoints(struct list_head *evlist); > > const char *event_type(int type); > @@ -46,8 +37,6 @@ int parse_events_terms(struct list_head *terms, const char *str); > int parse_filter(const struct option *opt, const char *str, int unset); > int exclude_perf(const struct option *opt, const char *arg, int unset); > > -#define EVENTS_HELP_MAX (128*1024) > - > enum perf_pmu_event_symbol_type { > PMU_EVENT_SYMBOL_ERR, /* not a PMU EVENT */ > PMU_EVENT_SYMBOL, /* normal style PMU event */ > @@ -55,11 +44,6 @@ enum perf_pmu_event_symbol_type { > PMU_EVENT_SYMBOL_SUFFIX, /* suffix of pre-suf style event */ > }; > > -struct perf_pmu_event_symbol { > - char *symbol; > - enum perf_pmu_event_symbol_type type; > -}; > - > enum { > PARSE_EVENTS__TERM_TYPE_NUM, > PARSE_EVENTS__TERM_TYPE_STR, > @@ -216,8 +200,6 @@ void parse_events_update_lists(struct list_head *list_event, > void parse_events_evlist_error(struct parse_events_state *parse_state, > int idx, const char *str); > > -void print_events(const char *event_glob, bool name_only, bool quiet, > - bool long_desc, bool details_flag, bool deprecated); > > struct event_symbol { > const char *symbol; > @@ -225,18 +207,7 @@ struct event_symbol { > }; > extern struct event_symbol event_symbols_hw[]; > extern struct event_symbol event_symbols_sw[]; > -void print_symbol_events(const char *event_glob, unsigned type, > - struct event_symbol *syms, unsigned max, > - bool name_only); > -void print_tool_events(const char *event_glob, bool name_only); > -void print_tracepoint_events(const char *subsys_glob, const char *event_glob, > - bool name_only); > -int print_hwcache_events(const char *event_glob, bool name_only); > -void print_sdt_events(const char *subsys_glob, const char *event_glob, > - bool name_only); > -int is_valid_tracepoint(const char *event_string); > > -int valid_event_mount(const char *eventfs); > char *parse_events_formats_error_string(char *additional_terms); > > void parse_events_print_error(struct parse_events_error *err, > diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c > new file mode 100644 > index 000000000000..584888353d13 > --- /dev/null > +++ b/tools/perf/util/print-events.c > @@ -0,0 +1,472 @@ > +// SPDX-License-Identifier: GPL-2.0 > +#include <dirent.h> > +#include <errno.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <string.h> > +#include <sys/param.h> > + > +#include <api/fs/tracing_path.h> > +#include <linux/perf_event.h> > +#include <linux/zalloc.h> > +#include <subcmd/pager.h> > + > +#include "build-id.h" > +#include "debug.h" > +#include "evsel.h" > +#include "metricgroup.h" > +#include "parse-events.h" > +#include "pmu.h" > +#include "print-events.h" > +#include "probe-file.h" > +#include "string2.h" > +#include "strlist.h" > +#include "thread_map.h" > +#include "tracepoint.h" > +#include "pfm.h" > + > +#define MAX_NAME_LEN 100 > + > +static int cmp_string(const void *a, const void *b) > +{ > + const char * const *as = a; > + const char * const *bs = b; > + > + return strcmp(*as, *bs); > +} > + > +static const char * const event_type_descriptors[] = { > + "Hardware event", > + "Software event", > + "Tracepoint event", > + "Hardware cache event", > + "Raw hardware event descriptor", > + "Hardware breakpoint", > +}; > + > +/* > + * Print the events from <debugfs_mount_point>/tracing/events > + */ > +void print_tracepoint_events(const char *subsys_glob, > + const char *event_glob, bool name_only) > +{ > + DIR *sys_dir, *evt_dir; > + struct dirent *sys_dirent, *evt_dirent; > + char evt_path[MAXPATHLEN]; > + char *dir_path; > + char **evt_list = NULL; > + unsigned int evt_i = 0, evt_num = 0; > + bool evt_num_known = false; > + > +restart: > + sys_dir = tracing_events__opendir(); > + if (!sys_dir) > + return; > + > + if (evt_num_known) { > + evt_list = zalloc(sizeof(char *) * evt_num); > + if (!evt_list) > + goto out_close_sys_dir; > + } > + > + for_each_subsystem(sys_dir, sys_dirent) { > + if (subsys_glob != NULL && > + !strglobmatch(sys_dirent->d_name, subsys_glob)) > + continue; > + > + dir_path = get_events_file(sys_dirent->d_name); > + if (!dir_path) > + continue; > + evt_dir = opendir(dir_path); > + if (!evt_dir) > + goto next; > + > + for_each_event(dir_path, evt_dir, evt_dirent) { > + if (event_glob != NULL && > + !strglobmatch(evt_dirent->d_name, event_glob)) > + continue; > + > + if (!evt_num_known) { > + evt_num++; > + continue; > + } > + > + snprintf(evt_path, MAXPATHLEN, "%s:%s", > + sys_dirent->d_name, evt_dirent->d_name); > + > + evt_list[evt_i] = strdup(evt_path); > + if (evt_list[evt_i] == NULL) { > + put_events_file(dir_path); > + goto out_close_evt_dir; > + } > + evt_i++; > + } > + closedir(evt_dir); > +next: > + put_events_file(dir_path); > + } > + closedir(sys_dir); > + > + if (!evt_num_known) { > + evt_num_known = true; > + goto restart; > + } > + qsort(evt_list, evt_num, sizeof(char *), cmp_string); > + evt_i = 0; > + while (evt_i < evt_num) { > + if (name_only) { > + printf("%s ", evt_list[evt_i++]); > + continue; > + } > + printf(" %-50s [%s]\n", evt_list[evt_i++], > + event_type_descriptors[PERF_TYPE_TRACEPOINT]); > + } > + if (evt_num && pager_in_use()) > + printf("\n"); > + > +out_free: > + evt_num = evt_i; > + for (evt_i = 0; evt_i < evt_num; evt_i++) > + zfree(&evt_list[evt_i]); > + zfree(&evt_list); > + return; > + > +out_close_evt_dir: > + closedir(evt_dir); > +out_close_sys_dir: > + closedir(sys_dir); > + > + printf("FATAL: not enough memory to print %s\n", > + event_type_descriptors[PERF_TYPE_TRACEPOINT]); > + if (evt_list) > + goto out_free; > +} > + > +void print_sdt_events(const char *subsys_glob, const char *event_glob, > + bool name_only) > +{ > + struct probe_cache *pcache; > + struct probe_cache_entry *ent; > + struct strlist *bidlist, *sdtlist; > + struct strlist_config cfg = {.dont_dupstr = true}; > + struct str_node *nd, *nd2; > + char *buf, *path, *ptr = NULL; > + bool show_detail = false; > + int ret; > + > + sdtlist = strlist__new(NULL, &cfg); > + if (!sdtlist) { > + pr_debug("Failed to allocate new strlist for SDT\n"); > + return; > + } > + bidlist = build_id_cache__list_all(true); > + if (!bidlist) { > + pr_debug("Failed to get buildids: %d\n", errno); > + return; > + } > + strlist__for_each_entry(nd, bidlist) { > + pcache = probe_cache__new(nd->s, NULL); > + if (!pcache) > + continue; > + list_for_each_entry(ent, &pcache->entries, node) { > + if (!ent->sdt) > + continue; > + if (subsys_glob && > + !strglobmatch(ent->pev.group, subsys_glob)) > + continue; > + if (event_glob && > + !strglobmatch(ent->pev.event, event_glob)) > + continue; > + ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, > + ent->pev.event, nd->s); > + if (ret > 0) > + strlist__add(sdtlist, buf); > + } > + probe_cache__delete(pcache); > + } > + strlist__delete(bidlist); > + > + strlist__for_each_entry(nd, sdtlist) { > + buf = strchr(nd->s, '@'); > + if (buf) > + *(buf++) = '\0'; > + if (name_only) { > + printf("%s ", nd->s); > + continue; > + } > + nd2 = strlist__next(nd); > + if (nd2) { > + ptr = strchr(nd2->s, '@'); > + if (ptr) > + *ptr = '\0'; > + if (strcmp(nd->s, nd2->s) == 0) > + show_detail = true; > + } > + if (show_detail) { > + path = build_id_cache__origname(buf); > + ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf); > + if (ret > 0) { > + printf(" %-50s [%s]\n", buf, "SDT event"); > + free(buf); > + } > + free(path); > + } else > + printf(" %-50s [%s]\n", nd->s, "SDT event"); > + if (nd2) { > + if (strcmp(nd->s, nd2->s) != 0) > + show_detail = false; > + if (ptr) > + *ptr = '@'; > + } > + } > + strlist__delete(sdtlist); > +} > + > +static bool is_event_supported(u8 type, unsigned int config) > +{ > + bool ret = true; > + int open_return; > + struct evsel *evsel; > + struct perf_event_attr attr = { > + .type = type, > + .config = config, > + .disabled = 1, > + }; > + struct perf_thread_map *tmap = thread_map__new_by_tid(0); > + > + if (tmap == NULL) > + return false; > + > + evsel = evsel__new(&attr); > + if (evsel) { > + open_return = evsel__open(evsel, NULL, tmap); > + ret = open_return >= 0; > + > + if (open_return == -EACCES) { > + /* > + * This happens if the paranoid value > + * /proc/sys/kernel/perf_event_paranoid is set to 2 > + * Re-run with exclude_kernel set; we don't do that > + * by default as some ARM machines do not support it. > + * > + */ > + evsel->core.attr.exclude_kernel = 1; > + ret = evsel__open(evsel, NULL, tmap) >= 0; > + } > + evsel__delete(evsel); > + } > + > + perf_thread_map__put(tmap); > + return ret; > +} > + > +int print_hwcache_events(const char *event_glob, bool name_only) > +{ > + unsigned int type, op, i, evt_i = 0, evt_num = 0; > + char name[64]; > + char **evt_list = NULL; > + bool evt_num_known = false; > + > +restart: > + if (evt_num_known) { > + evt_list = zalloc(sizeof(char *) * evt_num); > + if (!evt_list) > + goto out_enomem; > + } > + > + for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { > + for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { > + /* skip invalid cache type */ > + if (!evsel__is_cache_op_valid(type, op)) > + continue; > + > + for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { > + __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); > + if (event_glob != NULL && !strglobmatch(name, event_glob)) > + continue; > + > + if (!is_event_supported(PERF_TYPE_HW_CACHE, > + type | (op << 8) | (i << 16))) > + continue; > + > + if (!evt_num_known) { > + evt_num++; > + continue; > + } > + > + evt_list[evt_i] = strdup(name); > + if (evt_list[evt_i] == NULL) > + goto out_enomem; > + evt_i++; > + } > + } > + } > + > + if (!evt_num_known) { > + evt_num_known = true; > + goto restart; > + } > + qsort(evt_list, evt_num, sizeof(char *), cmp_string); > + evt_i = 0; > + while (evt_i < evt_num) { > + if (name_only) { > + printf("%s ", evt_list[evt_i++]); > + continue; > + } > + printf(" %-50s [%s]\n", evt_list[evt_i++], > + event_type_descriptors[PERF_TYPE_HW_CACHE]); > + } > + if (evt_num && pager_in_use()) > + printf("\n"); > + > +out_free: > + evt_num = evt_i; > + for (evt_i = 0; evt_i < evt_num; evt_i++) > + zfree(&evt_list[evt_i]); > + zfree(&evt_list); > + return evt_num; > + > +out_enomem: > + printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]); > + if (evt_list) > + goto out_free; > + return evt_num; > +} > + > +static void print_tool_event(const char *name, const char *event_glob, > + bool name_only) > +{ > + if (event_glob && !strglobmatch(name, event_glob)) > + return; > + if (name_only) > + printf("%s ", name); > + else > + printf(" %-50s [%s]\n", name, "Tool event"); > + > +} > + > +void print_tool_events(const char *event_glob, bool name_only) > +{ > + print_tool_event("duration_time", event_glob, name_only); > + if (pager_in_use()) > + printf("\n"); > +} > + > +void print_symbol_events(const char *event_glob, unsigned int type, > + struct event_symbol *syms, unsigned int max, > + bool name_only) > +{ > + unsigned int i, evt_i = 0, evt_num = 0; > + char name[MAX_NAME_LEN]; > + char **evt_list = NULL; > + bool evt_num_known = false; > + > +restart: > + if (evt_num_known) { > + evt_list = zalloc(sizeof(char *) * evt_num); > + if (!evt_list) > + goto out_enomem; > + syms -= max; > + } > + > + for (i = 0; i < max; i++, syms++) { > + > + if (event_glob != NULL && syms->symbol != NULL && > + !(strglobmatch(syms->symbol, event_glob) || > + (syms->alias && strglobmatch(syms->alias, event_glob)))) > + continue; > + > + if (!is_event_supported(type, i)) > + continue; > + > + if (!evt_num_known) { > + evt_num++; > + continue; > + } > + > + if (!name_only && strlen(syms->alias)) > + snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); > + else > + strlcpy(name, syms->symbol, MAX_NAME_LEN); > + > + evt_list[evt_i] = strdup(name); > + if (evt_list[evt_i] == NULL) > + goto out_enomem; > + evt_i++; > + } > + > + if (!evt_num_known) { > + evt_num_known = true; > + goto restart; > + } > + qsort(evt_list, evt_num, sizeof(char *), cmp_string); > + evt_i = 0; > + while (evt_i < evt_num) { > + if (name_only) { > + printf("%s ", evt_list[evt_i++]); > + continue; > + } > + printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); > + } > + if (evt_num && pager_in_use()) > + printf("\n"); > + > +out_free: > + evt_num = evt_i; > + for (evt_i = 0; evt_i < evt_num; evt_i++) > + zfree(&evt_list[evt_i]); > + zfree(&evt_list); > + return; > + > +out_enomem: > + printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); > + if (evt_list) > + goto out_free; > +} > + > +/* > + * Print the help text for the event symbols: > + */ > +void print_events(const char *event_glob, bool name_only, bool quiet_flag, > + bool long_desc, bool details_flag, bool deprecated) > +{ > + print_symbol_events(event_glob, PERF_TYPE_HARDWARE, > + event_symbols_hw, PERF_COUNT_HW_MAX, name_only); > + > + print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, > + event_symbols_sw, PERF_COUNT_SW_MAX, name_only); > + print_tool_events(event_glob, name_only); > + > + print_hwcache_events(event_glob, name_only); > + > + print_pmu_events(event_glob, name_only, quiet_flag, long_desc, > + details_flag, deprecated); > + > + if (event_glob != NULL) > + return; > + > + if (!name_only) { > + printf(" %-50s [%s]\n", > + "rNNN", > + event_type_descriptors[PERF_TYPE_RAW]); > + printf(" %-50s [%s]\n", > + "cpu/t1=v1[,t2=v2,t3 ...]/modifier", > + event_type_descriptors[PERF_TYPE_RAW]); > + if (pager_in_use()) > + printf(" (see 'man perf-list' on how to encode it)\n\n"); > + > + printf(" %-50s [%s]\n", > + "mem:<addr>[/len][:access]", > + event_type_descriptors[PERF_TYPE_BREAKPOINT]); > + if (pager_in_use()) > + printf("\n"); > + } > + > + print_tracepoint_events(NULL, NULL, name_only); > + > + print_sdt_events(NULL, NULL, name_only); > + > + metricgroup__print(true, true, NULL, name_only, details_flag); > + > + print_libpfm_events(name_only, long_desc); > +} > diff --git a/tools/perf/util/print-events.h b/tools/perf/util/print-events.h > new file mode 100644 > index 000000000000..cf64e8129c1b > --- /dev/null > +++ b/tools/perf/util/print-events.h > @@ -0,0 +1,21 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef __PERF_PRINT_EVENTS_H > +#define __PERF_PRINT_EVENTS_H > + > +#include <stdbool.h> > + > +struct event_symbol; > + > +void print_events(const char *event_glob, bool name_only, bool quiet, > + bool long_desc, bool details_flag, bool deprecated); > +int print_hwcache_events(const char *event_glob, bool name_only); > +void print_sdt_events(const char *subsys_glob, const char *event_glob, > + bool name_only); > +void print_symbol_events(const char *event_glob, unsigned int type, > + struct event_symbol *syms, unsigned int max, > + bool name_only); > +void print_tool_events(const char *event_glob, bool name_only); > +void print_tracepoint_events(const char *subsys_glob, const char *event_glob, > + bool name_only); > + > +#endif /* __PERF_PRINT_EVENTS_H */ > diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c > index a65f65d0857e..fbc6d14aabbb 100644 > --- a/tools/perf/util/trace-event-info.c > +++ b/tools/perf/util/trace-event-info.c > @@ -19,16 +19,24 @@ > #include <linux/kernel.h> > #include <linux/zalloc.h> > #include <internal/lib.h> // page_size > +#include <sys/param.h> > > #include "trace-event.h" > +#include "tracepoint.h" > #include <api/fs/tracing_path.h> > #include "evsel.h" > #include "debug.h" > > #define VERSION "0.6" > +#define MAX_EVENT_LENGTH 512 > > static int output_fd; > > +struct tracepoint_path { > + char *system; > + char *name; > + struct tracepoint_path *next; > +}; > > int bigendian(void) > { > @@ -400,6 +408,92 @@ put_tracepoints_path(struct tracepoint_path *tps) > } > } > > +static struct tracepoint_path *tracepoint_id_to_path(u64 config) > +{ > + struct tracepoint_path *path = NULL; > + DIR *sys_dir, *evt_dir; > + struct dirent *sys_dirent, *evt_dirent; > + char id_buf[24]; > + int fd; > + u64 id; > + char evt_path[MAXPATHLEN]; > + char *dir_path; > + > + sys_dir = tracing_events__opendir(); > + if (!sys_dir) > + return NULL; > + > + for_each_subsystem(sys_dir, sys_dirent) { > + dir_path = get_events_file(sys_dirent->d_name); > + if (!dir_path) > + continue; > + evt_dir = opendir(dir_path); > + if (!evt_dir) > + goto next; > + > + for_each_event(dir_path, evt_dir, evt_dirent) { > + > + scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, > + evt_dirent->d_name); > + fd = open(evt_path, O_RDONLY); > + if (fd < 0) > + continue; > + if (read(fd, id_buf, sizeof(id_buf)) < 0) { > + close(fd); > + continue; > + } > + close(fd); > + id = atoll(id_buf); > + if (id == config) { > + put_events_file(dir_path); > + closedir(evt_dir); > + closedir(sys_dir); > + path = zalloc(sizeof(*path)); > + if (!path) > + return NULL; > + if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { > + free(path); > + return NULL; > + } > + if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { > + zfree(&path->system); > + free(path); > + return NULL; > + } > + return path; > + } > + } > + closedir(evt_dir); > +next: > + put_events_file(dir_path); > + } > + > + closedir(sys_dir); > + return NULL; > +} > + > +static struct tracepoint_path *tracepoint_name_to_path(const char *name) > +{ > + struct tracepoint_path *path = zalloc(sizeof(*path)); > + char *str = strchr(name, ':'); > + > + if (path == NULL || str == NULL) { > + free(path); > + return NULL; > + } > + > + path->system = strndup(name, str - name); > + path->name = strdup(str+1); > + > + if (path->system == NULL || path->name == NULL) { > + zfree(&path->system); > + zfree(&path->name); > + zfree(&path); > + } > + > + return path; > +} > + > static struct tracepoint_path * > get_tracepoints_path(struct list_head *pattrs) > { > diff --git a/tools/perf/util/tracepoint.c b/tools/perf/util/tracepoint.c > new file mode 100644 > index 000000000000..89ef56c43311 > --- /dev/null > +++ b/tools/perf/util/tracepoint.c > @@ -0,0 +1,63 @@ > +// SPDX-License-Identifier: GPL-2.0 > +#include "tracepoint.h" > + > +#include <errno.h> > +#include <fcntl.h> > +#include <stdio.h> > +#include <sys/param.h> > +#include <unistd.h> > + > +#include <api/fs/tracing_path.h> > + > +int tp_event_has_id(const char *dir_path, struct dirent *evt_dir) > +{ > + char evt_path[MAXPATHLEN]; > + int fd; > + > + snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, evt_dir->d_name); > + fd = open(evt_path, O_RDONLY); > + if (fd < 0) > + return -EINVAL; > + close(fd); > + > + return 0; > +} > + > +/* > + * Check whether event is in <debugfs_mount_point>/tracing/events > + */ > +int is_valid_tracepoint(const char *event_string) > +{ > + DIR *sys_dir, *evt_dir; > + struct dirent *sys_dirent, *evt_dirent; > + char evt_path[MAXPATHLEN]; > + char *dir_path; > + > + sys_dir = tracing_events__opendir(); > + if (!sys_dir) > + return 0; > + > + for_each_subsystem(sys_dir, sys_dirent) { > + dir_path = get_events_file(sys_dirent->d_name); > + if (!dir_path) > + continue; > + evt_dir = opendir(dir_path); > + if (!evt_dir) > + goto next; > + > + for_each_event(dir_path, evt_dir, evt_dirent) { > + snprintf(evt_path, MAXPATHLEN, "%s:%s", > + sys_dirent->d_name, evt_dirent->d_name); > + if (!strcmp(evt_path, event_string)) { > + closedir(evt_dir); > + closedir(sys_dir); > + return 1; > + } > + } > + closedir(evt_dir); > +next: > + put_events_file(dir_path); > + } > + closedir(sys_dir); > + return 0; > +} > diff --git a/tools/perf/util/tracepoint.h b/tools/perf/util/tracepoint.h > new file mode 100644 > index 000000000000..c4a110fe87d7 > --- /dev/null > +++ b/tools/perf/util/tracepoint.h > @@ -0,0 +1,25 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +#ifndef __PERF_TRACEPOINT_H > +#define __PERF_TRACEPOINT_H > + > +#include <dirent.h> > +#include <string.h> > + > +int tp_event_has_id(const char *dir_path, struct dirent *evt_dir); > + > +#define for_each_event(dir_path, evt_dir, evt_dirent) \ > + while ((evt_dirent = readdir(evt_dir)) != NULL) \ > + if (evt_dirent->d_type == DT_DIR && \ > + (strcmp(evt_dirent->d_name, ".")) && \ > + (strcmp(evt_dirent->d_name, "..")) && \ > + (!tp_event_has_id(dir_path, evt_dirent))) > + > +#define for_each_subsystem(sys_dir, sys_dirent) \ > + while ((sys_dirent = readdir(sys_dir)) != NULL) \ > + if (sys_dirent->d_type == DT_DIR && \ > + (strcmp(sys_dirent->d_name, ".")) && \ > + (strcmp(sys_dirent->d_name, ".."))) > + > +int is_valid_tracepoint(const char *event_string); > + > +#endif /* __PERF_TRACEPOINT_H */ > -- > 2.30.0.365.g02bc693789-goog > -- - Arnaldo ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] perf parse-events: Break out tracepoint and printing. 2021-02-03 16:20 ` Arnaldo Carvalho de Melo @ 2021-02-03 19:02 ` Ian Rogers [not found] ` <CAP-5=fVFeT6YtXJGHX0OC1BCa121bTC+ER7XDVO2g5rr8DYfDw@mail.gmail.com> 1 sibling, 0 replies; 8+ messages in thread From: Ian Rogers @ 2021-02-03 19:02 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim, LKML, Stephane Eranian On Wed, Feb 3, 2021 at 8:21 AM Arnaldo Carvalho de Melo <acme@kernel.org> wrote: > > Em Tue, Feb 02, 2021 at 09:26:59PM -0800, Ian Rogers escreveu: > > Move print_*_events functions out of parse-events.c into a new > > print-events.c. Move tracepoint code into tracepoint.c or > > trace-event-info.c (sole user). This reduces the dependencies of > > parse-events.c and makes it more amenable to being a library in the > > future. > > Remove some unnecessary definitions from parse-events.h. Fix a > > checkpatch.pl warning on using unsigned rather than unsigned int. > > Thanks, applied. (Re-send enabling plain text mode) Wow, cool :-) I wasn't sure about the macros in the headers. Are you staging these patches before pushing to your perf/core or using tmp.perf/core ? I know you mentioned a different approach. When I look at: https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/ I don't see anything newer than 9 days. Thanks, Ian > > - Arnaldo > > > > Signed-off-by: Ian Rogers <irogers@google.com> > > --- > > tools/perf/builtin-list.c | 2 +- > > tools/perf/builtin-lock.c | 1 + > > tools/perf/builtin-timechart.c | 1 + > > tools/perf/builtin-trace.c | 1 + > > tools/perf/util/Build | 2 + > > tools/perf/util/parse-events.c | 620 +---------------------------- > > tools/perf/util/parse-events.h | 29 -- > > tools/perf/util/print-events.c | 472 ++++++++++++++++++++++ > > tools/perf/util/print-events.h | 21 + > > tools/perf/util/trace-event-info.c | 94 +++++ > > tools/perf/util/tracepoint.c | 63 +++ > > tools/perf/util/tracepoint.h | 25 ++ > > 12 files changed, 687 insertions(+), 644 deletions(-) > > create mode 100644 tools/perf/util/print-events.c > > create mode 100644 tools/perf/util/print-events.h > > create mode 100644 tools/perf/util/tracepoint.c > > create mode 100644 tools/perf/util/tracepoint.h > > > > diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c > > index 10ab5e40a34f..91327a321c36 100644 > > --- a/tools/perf/builtin-list.c > > +++ b/tools/perf/builtin-list.c > > @@ -10,7 +10,7 @@ > > */ > > #include "builtin.h" > > > > -#include "util/parse-events.h" > > +#include "util/print-events.h" > > #include "util/pmu.h" > > #include "util/debug.h" > > #include "util/metricgroup.h" > > diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c > > index a2f1e53f37a7..486123cb106e 100644 > > --- a/tools/perf/builtin-lock.c > > +++ b/tools/perf/builtin-lock.c > > @@ -13,6 +13,7 @@ > > #include <subcmd/pager.h> > > #include <subcmd/parse-options.h> > > #include "util/trace-event.h" > > +#include "util/tracepoint.h" > > > > #include "util/debug.h" > > #include "util/session.h" > > diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c > > index 4e380e7b5230..cdebcf26f408 100644 > > --- a/tools/perf/builtin-timechart.c > > +++ b/tools/perf/builtin-timechart.c > > @@ -35,6 +35,7 @@ > > #include "util/tool.h" > > #include "util/data.h" > > #include "util/debug.h" > > +#include "util/tracepoint.h" > > #include <linux/err.h> > > > > #ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE > > diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c > > index 85b6a46e85b6..b3b9fa1c7731 100644 > > --- a/tools/perf/builtin-trace.c > > +++ b/tools/perf/builtin-trace.c > > @@ -53,6 +53,7 @@ > > #include "trace-event.h" > > #include "util/parse-events.h" > > #include "util/bpf-loader.h" > > +#include "util/tracepoint.h" > > #include "callchain.h" > > #include "print_binary.h" > > #include "string2.h" > > diff --git a/tools/perf/util/Build b/tools/perf/util/Build > > index 188521f34347..c2c9f3f490e8 100644 > > --- a/tools/perf/util/Build > > +++ b/tools/perf/util/Build > > @@ -23,6 +23,8 @@ perf-y += llvm-utils.o > > perf-y += mmap.o > > perf-y += memswap.o > > perf-y += parse-events.o > > +perf-y += print-events.o > > +perf-y += tracepoint.o > > perf-y += perf_regs.o > > perf-y += path.o > > perf-y += print_binary.o > > diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c > > index 42c84adeb2fb..5d5ebb700ef2 100644 > > --- a/tools/perf/util/parse-events.c > > +++ b/tools/perf/util/parse-events.c > > @@ -5,42 +5,34 @@ > > #include <dirent.h> > > #include <errno.h> > > #include <sys/ioctl.h> > > -#include <sys/types.h> > > -#include <sys/stat.h> > > -#include <fcntl.h> > > #include <sys/param.h> > > #include "term.h" > > -#include "build-id.h" > > #include "evlist.h" > > #include "evsel.h" > > -#include <subcmd/pager.h> > > #include <subcmd/parse-options.h> > > #include "parse-events.h" > > -#include <subcmd/exec-cmd.h> > > #include "string2.h" > > -#include "strlist.h" > > -#include "symbol.h" > > -#include "header.h" > > #include "bpf-loader.h" > > #include "debug.h" > > #include <api/fs/tracing_path.h> > > #include <perf/cpumap.h> > > #include "parse-events-bison.h" > > -#define YY_EXTRA_TYPE void* > > #include "parse-events-flex.h" > > #include "pmu.h" > > -#include "thread_map.h" > > -#include "probe-file.h" > > #include "asm/bug.h" > > #include "util/parse-branch-options.h" > > -#include "metricgroup.h" > > #include "util/evsel_config.h" > > #include "util/event.h" > > -#include "util/pfm.h" > > #include "perf.h" > > +#include "tracepoint.h" > > > > #define MAX_NAME_LEN 100 > > > > +struct perf_pmu_event_symbol { > > + char *symbol; > > + enum perf_pmu_event_symbol_type type; > > +}; > > + > > #ifdef PARSER_DEBUG > > extern int parse_events_debug; > > #endif > > @@ -155,35 +147,6 @@ struct event_symbol event_symbols_sw[PERF_COUNT_SW_MAX] = { > > #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) > > #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) > > > > -#define for_each_subsystem(sys_dir, sys_dirent) \ > > - while ((sys_dirent = readdir(sys_dir)) != NULL) \ > > - if (sys_dirent->d_type == DT_DIR && \ > > - (strcmp(sys_dirent->d_name, ".")) && \ > > - (strcmp(sys_dirent->d_name, ".."))) > > - > > -static int tp_event_has_id(const char *dir_path, struct dirent *evt_dir) > > -{ > > - char evt_path[MAXPATHLEN]; > > - int fd; > > - > > - snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, evt_dir->d_name); > > - fd = open(evt_path, O_RDONLY); > > - if (fd < 0) > > - return -EINVAL; > > - close(fd); > > - > > - return 0; > > -} > > - > > -#define for_each_event(dir_path, evt_dir, evt_dirent) \ > > - while ((evt_dirent = readdir(evt_dir)) != NULL) \ > > - if (evt_dirent->d_type == DT_DIR && \ > > - (strcmp(evt_dirent->d_name, ".")) && \ > > - (strcmp(evt_dirent->d_name, "..")) && \ > > - (!tp_event_has_id(dir_path, evt_dirent))) > > - > > -#define MAX_EVENT_LENGTH 512 > > - > > void parse_events__handle_error(struct parse_events_error *err, int idx, > > char *str, char *help) > > { > > @@ -217,92 +180,6 @@ void parse_events__handle_error(struct parse_events_error *err, int idx, > > err->num_errors++; > > } > > > > -struct tracepoint_path *tracepoint_id_to_path(u64 config) > > -{ > > - struct tracepoint_path *path = NULL; > > - DIR *sys_dir, *evt_dir; > > - struct dirent *sys_dirent, *evt_dirent; > > - char id_buf[24]; > > - int fd; > > - u64 id; > > - char evt_path[MAXPATHLEN]; > > - char *dir_path; > > - > > - sys_dir = tracing_events__opendir(); > > - if (!sys_dir) > > - return NULL; > > - > > - for_each_subsystem(sys_dir, sys_dirent) { > > - dir_path = get_events_file(sys_dirent->d_name); > > - if (!dir_path) > > - continue; > > - evt_dir = opendir(dir_path); > > - if (!evt_dir) > > - goto next; > > - > > - for_each_event(dir_path, evt_dir, evt_dirent) { > > - > > - scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, > > - evt_dirent->d_name); > > - fd = open(evt_path, O_RDONLY); > > - if (fd < 0) > > - continue; > > - if (read(fd, id_buf, sizeof(id_buf)) < 0) { > > - close(fd); > > - continue; > > - } > > - close(fd); > > - id = atoll(id_buf); > > - if (id == config) { > > - put_events_file(dir_path); > > - closedir(evt_dir); > > - closedir(sys_dir); > > - path = zalloc(sizeof(*path)); > > - if (!path) > > - return NULL; > > - if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { > > - free(path); > > - return NULL; > > - } > > - if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { > > - zfree(&path->system); > > - free(path); > > - return NULL; > > - } > > - return path; > > - } > > - } > > - closedir(evt_dir); > > -next: > > - put_events_file(dir_path); > > - } > > - > > - closedir(sys_dir); > > - return NULL; > > -} > > - > > -struct tracepoint_path *tracepoint_name_to_path(const char *name) > > -{ > > - struct tracepoint_path *path = zalloc(sizeof(*path)); > > - char *str = strchr(name, ':'); > > - > > - if (path == NULL || str == NULL) { > > - free(path); > > - return NULL; > > - } > > - > > - path->system = strndup(name, str - name); > > - path->name = strdup(str+1); > > - > > - if (path->system == NULL || path->name == NULL) { > > - zfree(&path->system); > > - zfree(&path->name); > > - zfree(&path); > > - } > > - > > - return path; > > -} > > - > > const char *event_type(int type) > > { > > switch (type) { > > @@ -2451,491 +2328,6 @@ int exclude_perf(const struct option *opt, > > NULL); > > } > > > > -static const char * const event_type_descriptors[] = { > > - "Hardware event", > > - "Software event", > > - "Tracepoint event", > > - "Hardware cache event", > > - "Raw hardware event descriptor", > > - "Hardware breakpoint", > > -}; > > - > > -static int cmp_string(const void *a, const void *b) > > -{ > > - const char * const *as = a; > > - const char * const *bs = b; > > - > > - return strcmp(*as, *bs); > > -} > > - > > -/* > > - * Print the events from <debugfs_mount_point>/tracing/events > > - */ > > - > > -void print_tracepoint_events(const char *subsys_glob, const char *event_glob, > > - bool name_only) > > -{ > > - DIR *sys_dir, *evt_dir; > > - struct dirent *sys_dirent, *evt_dirent; > > - char evt_path[MAXPATHLEN]; > > - char *dir_path; > > - char **evt_list = NULL; > > - unsigned int evt_i = 0, evt_num = 0; > > - bool evt_num_known = false; > > - > > -restart: > > - sys_dir = tracing_events__opendir(); > > - if (!sys_dir) > > - return; > > - > > - if (evt_num_known) { > > - evt_list = zalloc(sizeof(char *) * evt_num); > > - if (!evt_list) > > - goto out_close_sys_dir; > > - } > > - > > - for_each_subsystem(sys_dir, sys_dirent) { > > - if (subsys_glob != NULL && > > - !strglobmatch(sys_dirent->d_name, subsys_glob)) > > - continue; > > - > > - dir_path = get_events_file(sys_dirent->d_name); > > - if (!dir_path) > > - continue; > > - evt_dir = opendir(dir_path); > > - if (!evt_dir) > > - goto next; > > - > > - for_each_event(dir_path, evt_dir, evt_dirent) { > > - if (event_glob != NULL && > > - !strglobmatch(evt_dirent->d_name, event_glob)) > > - continue; > > - > > - if (!evt_num_known) { > > - evt_num++; > > - continue; > > - } > > - > > - snprintf(evt_path, MAXPATHLEN, "%s:%s", > > - sys_dirent->d_name, evt_dirent->d_name); > > - > > - evt_list[evt_i] = strdup(evt_path); > > - if (evt_list[evt_i] == NULL) { > > - put_events_file(dir_path); > > - goto out_close_evt_dir; > > - } > > - evt_i++; > > - } > > - closedir(evt_dir); > > -next: > > - put_events_file(dir_path); > > - } > > - closedir(sys_dir); > > - > > - if (!evt_num_known) { > > - evt_num_known = true; > > - goto restart; > > - } > > - qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > - evt_i = 0; > > - while (evt_i < evt_num) { > > - if (name_only) { > > - printf("%s ", evt_list[evt_i++]); > > - continue; > > - } > > - printf(" %-50s [%s]\n", evt_list[evt_i++], > > - event_type_descriptors[PERF_TYPE_TRACEPOINT]); > > - } > > - if (evt_num && pager_in_use()) > > - printf("\n"); > > - > > -out_free: > > - evt_num = evt_i; > > - for (evt_i = 0; evt_i < evt_num; evt_i++) > > - zfree(&evt_list[evt_i]); > > - zfree(&evt_list); > > - return; > > - > > -out_close_evt_dir: > > - closedir(evt_dir); > > -out_close_sys_dir: > > - closedir(sys_dir); > > - > > - printf("FATAL: not enough memory to print %s\n", > > - event_type_descriptors[PERF_TYPE_TRACEPOINT]); > > - if (evt_list) > > - goto out_free; > > -} > > - > > -/* > > - * Check whether event is in <debugfs_mount_point>/tracing/events > > - */ > > - > > -int is_valid_tracepoint(const char *event_string) > > -{ > > - DIR *sys_dir, *evt_dir; > > - struct dirent *sys_dirent, *evt_dirent; > > - char evt_path[MAXPATHLEN]; > > - char *dir_path; > > - > > - sys_dir = tracing_events__opendir(); > > - if (!sys_dir) > > - return 0; > > - > > - for_each_subsystem(sys_dir, sys_dirent) { > > - dir_path = get_events_file(sys_dirent->d_name); > > - if (!dir_path) > > - continue; > > - evt_dir = opendir(dir_path); > > - if (!evt_dir) > > - goto next; > > - > > - for_each_event(dir_path, evt_dir, evt_dirent) { > > - snprintf(evt_path, MAXPATHLEN, "%s:%s", > > - sys_dirent->d_name, evt_dirent->d_name); > > - if (!strcmp(evt_path, event_string)) { > > - closedir(evt_dir); > > - closedir(sys_dir); > > - return 1; > > - } > > - } > > - closedir(evt_dir); > > -next: > > - put_events_file(dir_path); > > - } > > - closedir(sys_dir); > > - return 0; > > -} > > - > > -static bool is_event_supported(u8 type, unsigned config) > > -{ > > - bool ret = true; > > - int open_return; > > - struct evsel *evsel; > > - struct perf_event_attr attr = { > > - .type = type, > > - .config = config, > > - .disabled = 1, > > - }; > > - struct perf_thread_map *tmap = thread_map__new_by_tid(0); > > - > > - if (tmap == NULL) > > - return false; > > - > > - evsel = evsel__new(&attr); > > - if (evsel) { > > - open_return = evsel__open(evsel, NULL, tmap); > > - ret = open_return >= 0; > > - > > - if (open_return == -EACCES) { > > - /* > > - * This happens if the paranoid value > > - * /proc/sys/kernel/perf_event_paranoid is set to 2 > > - * Re-run with exclude_kernel set; we don't do that > > - * by default as some ARM machines do not support it. > > - * > > - */ > > - evsel->core.attr.exclude_kernel = 1; > > - ret = evsel__open(evsel, NULL, tmap) >= 0; > > - } > > - evsel__delete(evsel); > > - } > > - > > - perf_thread_map__put(tmap); > > - return ret; > > -} > > - > > -void print_sdt_events(const char *subsys_glob, const char *event_glob, > > - bool name_only) > > -{ > > - struct probe_cache *pcache; > > - struct probe_cache_entry *ent; > > - struct strlist *bidlist, *sdtlist; > > - struct strlist_config cfg = {.dont_dupstr = true}; > > - struct str_node *nd, *nd2; > > - char *buf, *path, *ptr = NULL; > > - bool show_detail = false; > > - int ret; > > - > > - sdtlist = strlist__new(NULL, &cfg); > > - if (!sdtlist) { > > - pr_debug("Failed to allocate new strlist for SDT\n"); > > - return; > > - } > > - bidlist = build_id_cache__list_all(true); > > - if (!bidlist) { > > - pr_debug("Failed to get buildids: %d\n", errno); > > - return; > > - } > > - strlist__for_each_entry(nd, bidlist) { > > - pcache = probe_cache__new(nd->s, NULL); > > - if (!pcache) > > - continue; > > - list_for_each_entry(ent, &pcache->entries, node) { > > - if (!ent->sdt) > > - continue; > > - if (subsys_glob && > > - !strglobmatch(ent->pev.group, subsys_glob)) > > - continue; > > - if (event_glob && > > - !strglobmatch(ent->pev.event, event_glob)) > > - continue; > > - ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, > > - ent->pev.event, nd->s); > > - if (ret > 0) > > - strlist__add(sdtlist, buf); > > - } > > - probe_cache__delete(pcache); > > - } > > - strlist__delete(bidlist); > > - > > - strlist__for_each_entry(nd, sdtlist) { > > - buf = strchr(nd->s, '@'); > > - if (buf) > > - *(buf++) = '\0'; > > - if (name_only) { > > - printf("%s ", nd->s); > > - continue; > > - } > > - nd2 = strlist__next(nd); > > - if (nd2) { > > - ptr = strchr(nd2->s, '@'); > > - if (ptr) > > - *ptr = '\0'; > > - if (strcmp(nd->s, nd2->s) == 0) > > - show_detail = true; > > - } > > - if (show_detail) { > > - path = build_id_cache__origname(buf); > > - ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf); > > - if (ret > 0) { > > - printf(" %-50s [%s]\n", buf, "SDT event"); > > - free(buf); > > - } > > - free(path); > > - } else > > - printf(" %-50s [%s]\n", nd->s, "SDT event"); > > - if (nd2) { > > - if (strcmp(nd->s, nd2->s) != 0) > > - show_detail = false; > > - if (ptr) > > - *ptr = '@'; > > - } > > - } > > - strlist__delete(sdtlist); > > -} > > - > > -int print_hwcache_events(const char *event_glob, bool name_only) > > -{ > > - unsigned int type, op, i, evt_i = 0, evt_num = 0; > > - char name[64]; > > - char **evt_list = NULL; > > - bool evt_num_known = false; > > - > > -restart: > > - if (evt_num_known) { > > - evt_list = zalloc(sizeof(char *) * evt_num); > > - if (!evt_list) > > - goto out_enomem; > > - } > > - > > - for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { > > - for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { > > - /* skip invalid cache type */ > > - if (!evsel__is_cache_op_valid(type, op)) > > - continue; > > - > > - for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { > > - __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); > > - if (event_glob != NULL && !strglobmatch(name, event_glob)) > > - continue; > > - > > - if (!is_event_supported(PERF_TYPE_HW_CACHE, > > - type | (op << 8) | (i << 16))) > > - continue; > > - > > - if (!evt_num_known) { > > - evt_num++; > > - continue; > > - } > > - > > - evt_list[evt_i] = strdup(name); > > - if (evt_list[evt_i] == NULL) > > - goto out_enomem; > > - evt_i++; > > - } > > - } > > - } > > - > > - if (!evt_num_known) { > > - evt_num_known = true; > > - goto restart; > > - } > > - qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > - evt_i = 0; > > - while (evt_i < evt_num) { > > - if (name_only) { > > - printf("%s ", evt_list[evt_i++]); > > - continue; > > - } > > - printf(" %-50s [%s]\n", evt_list[evt_i++], > > - event_type_descriptors[PERF_TYPE_HW_CACHE]); > > - } > > - if (evt_num && pager_in_use()) > > - printf("\n"); > > - > > -out_free: > > - evt_num = evt_i; > > - for (evt_i = 0; evt_i < evt_num; evt_i++) > > - zfree(&evt_list[evt_i]); > > - zfree(&evt_list); > > - return evt_num; > > - > > -out_enomem: > > - printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]); > > - if (evt_list) > > - goto out_free; > > - return evt_num; > > -} > > - > > -static void print_tool_event(const char *name, const char *event_glob, > > - bool name_only) > > -{ > > - if (event_glob && !strglobmatch(name, event_glob)) > > - return; > > - if (name_only) > > - printf("%s ", name); > > - else > > - printf(" %-50s [%s]\n", name, "Tool event"); > > - > > -} > > - > > -void print_tool_events(const char *event_glob, bool name_only) > > -{ > > - print_tool_event("duration_time", event_glob, name_only); > > - if (pager_in_use()) > > - printf("\n"); > > -} > > - > > -void print_symbol_events(const char *event_glob, unsigned type, > > - struct event_symbol *syms, unsigned max, > > - bool name_only) > > -{ > > - unsigned int i, evt_i = 0, evt_num = 0; > > - char name[MAX_NAME_LEN]; > > - char **evt_list = NULL; > > - bool evt_num_known = false; > > - > > -restart: > > - if (evt_num_known) { > > - evt_list = zalloc(sizeof(char *) * evt_num); > > - if (!evt_list) > > - goto out_enomem; > > - syms -= max; > > - } > > - > > - for (i = 0; i < max; i++, syms++) { > > - > > - if (event_glob != NULL && syms->symbol != NULL && > > - !(strglobmatch(syms->symbol, event_glob) || > > - (syms->alias && strglobmatch(syms->alias, event_glob)))) > > - continue; > > - > > - if (!is_event_supported(type, i)) > > - continue; > > - > > - if (!evt_num_known) { > > - evt_num++; > > - continue; > > - } > > - > > - if (!name_only && strlen(syms->alias)) > > - snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); > > - else > > - strlcpy(name, syms->symbol, MAX_NAME_LEN); > > - > > - evt_list[evt_i] = strdup(name); > > - if (evt_list[evt_i] == NULL) > > - goto out_enomem; > > - evt_i++; > > - } > > - > > - if (!evt_num_known) { > > - evt_num_known = true; > > - goto restart; > > - } > > - qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > - evt_i = 0; > > - while (evt_i < evt_num) { > > - if (name_only) { > > - printf("%s ", evt_list[evt_i++]); > > - continue; > > - } > > - printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); > > - } > > - if (evt_num && pager_in_use()) > > - printf("\n"); > > - > > -out_free: > > - evt_num = evt_i; > > - for (evt_i = 0; evt_i < evt_num; evt_i++) > > - zfree(&evt_list[evt_i]); > > - zfree(&evt_list); > > - return; > > - > > -out_enomem: > > - printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); > > - if (evt_list) > > - goto out_free; > > -} > > - > > -/* > > - * Print the help text for the event symbols: > > - */ > > -void print_events(const char *event_glob, bool name_only, bool quiet_flag, > > - bool long_desc, bool details_flag, bool deprecated) > > -{ > > - print_symbol_events(event_glob, PERF_TYPE_HARDWARE, > > - event_symbols_hw, PERF_COUNT_HW_MAX, name_only); > > - > > - print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, > > - event_symbols_sw, PERF_COUNT_SW_MAX, name_only); > > - print_tool_events(event_glob, name_only); > > - > > - print_hwcache_events(event_glob, name_only); > > - > > - print_pmu_events(event_glob, name_only, quiet_flag, long_desc, > > - details_flag, deprecated); > > - > > - if (event_glob != NULL) > > - return; > > - > > - if (!name_only) { > > - printf(" %-50s [%s]\n", > > - "rNNN", > > - event_type_descriptors[PERF_TYPE_RAW]); > > - printf(" %-50s [%s]\n", > > - "cpu/t1=v1[,t2=v2,t3 ...]/modifier", > > - event_type_descriptors[PERF_TYPE_RAW]); > > - if (pager_in_use()) > > - printf(" (see 'man perf-list' on how to encode it)\n\n"); > > - > > - printf(" %-50s [%s]\n", > > - "mem:<addr>[/len][:access]", > > - event_type_descriptors[PERF_TYPE_BREAKPOINT]); > > - if (pager_in_use()) > > - printf("\n"); > > - } > > - > > - print_tracepoint_events(NULL, NULL, name_only); > > - > > - print_sdt_events(NULL, NULL, name_only); > > - > > - metricgroup__print(true, true, NULL, name_only, details_flag); > > - > > - print_libpfm_events(name_only, long_desc); > > -} > > - > > int parse_events__is_hardcoded_term(struct parse_events_term *term) > > { > > return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; > > diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h > > index e80c9b74f2f2..7cea425e80f9 100644 > > --- a/tools/perf/util/parse-events.h > > +++ b/tools/perf/util/parse-events.h > > @@ -11,7 +11,6 @@ > > #include <linux/perf_event.h> > > #include <string.h> > > > > -struct list_head; > > struct evsel; > > struct evlist; > > struct parse_events_error; > > @@ -19,14 +18,6 @@ struct parse_events_error; > > struct option; > > struct perf_pmu; > > > > -struct tracepoint_path { > > - char *system; > > - char *name; > > - struct tracepoint_path *next; > > -}; > > - > > -struct tracepoint_path *tracepoint_id_to_path(u64 config); > > -struct tracepoint_path *tracepoint_name_to_path(const char *name); > > bool have_tracepoints(struct list_head *evlist); > > > > const char *event_type(int type); > > @@ -46,8 +37,6 @@ int parse_events_terms(struct list_head *terms, const char *str); > > int parse_filter(const struct option *opt, const char *str, int unset); > > int exclude_perf(const struct option *opt, const char *arg, int unset); > > > > -#define EVENTS_HELP_MAX (128*1024) > > - > > enum perf_pmu_event_symbol_type { > > PMU_EVENT_SYMBOL_ERR, /* not a PMU EVENT */ > > PMU_EVENT_SYMBOL, /* normal style PMU event */ > > @@ -55,11 +44,6 @@ enum perf_pmu_event_symbol_type { > > PMU_EVENT_SYMBOL_SUFFIX, /* suffix of pre-suf style event */ > > }; > > > > -struct perf_pmu_event_symbol { > > - char *symbol; > > - enum perf_pmu_event_symbol_type type; > > -}; > > - > > enum { > > PARSE_EVENTS__TERM_TYPE_NUM, > > PARSE_EVENTS__TERM_TYPE_STR, > > @@ -216,8 +200,6 @@ void parse_events_update_lists(struct list_head *list_event, > > void parse_events_evlist_error(struct parse_events_state *parse_state, > > int idx, const char *str); > > > > -void print_events(const char *event_glob, bool name_only, bool quiet, > > - bool long_desc, bool details_flag, bool deprecated); > > > > struct event_symbol { > > const char *symbol; > > @@ -225,18 +207,7 @@ struct event_symbol { > > }; > > extern struct event_symbol event_symbols_hw[]; > > extern struct event_symbol event_symbols_sw[]; > > -void print_symbol_events(const char *event_glob, unsigned type, > > - struct event_symbol *syms, unsigned max, > > - bool name_only); > > -void print_tool_events(const char *event_glob, bool name_only); > > -void print_tracepoint_events(const char *subsys_glob, const char *event_glob, > > - bool name_only); > > -int print_hwcache_events(const char *event_glob, bool name_only); > > -void print_sdt_events(const char *subsys_glob, const char *event_glob, > > - bool name_only); > > -int is_valid_tracepoint(const char *event_string); > > > > -int valid_event_mount(const char *eventfs); > > char *parse_events_formats_error_string(char *additional_terms); > > > > void parse_events_print_error(struct parse_events_error *err, > > diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c > > new file mode 100644 > > index 000000000000..584888353d13 > > --- /dev/null > > +++ b/tools/perf/util/print-events.c > > @@ -0,0 +1,472 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +#include <dirent.h> > > +#include <errno.h> > > +#include <stdio.h> > > +#include <stdlib.h> > > +#include <string.h> > > +#include <sys/param.h> > > + > > +#include <api/fs/tracing_path.h> > > +#include <linux/perf_event.h> > > +#include <linux/zalloc.h> > > +#include <subcmd/pager.h> > > + > > +#include "build-id.h" > > +#include "debug.h" > > +#include "evsel.h" > > +#include "metricgroup.h" > > +#include "parse-events.h" > > +#include "pmu.h" > > +#include "print-events.h" > > +#include "probe-file.h" > > +#include "string2.h" > > +#include "strlist.h" > > +#include "thread_map.h" > > +#include "tracepoint.h" > > +#include "pfm.h" > > + > > +#define MAX_NAME_LEN 100 > > + > > +static int cmp_string(const void *a, const void *b) > > +{ > > + const char * const *as = a; > > + const char * const *bs = b; > > + > > + return strcmp(*as, *bs); > > +} > > + > > +static const char * const event_type_descriptors[] = { > > + "Hardware event", > > + "Software event", > > + "Tracepoint event", > > + "Hardware cache event", > > + "Raw hardware event descriptor", > > + "Hardware breakpoint", > > +}; > > + > > +/* > > + * Print the events from <debugfs_mount_point>/tracing/events > > + */ > > +void print_tracepoint_events(const char *subsys_glob, > > + const char *event_glob, bool name_only) > > +{ > > + DIR *sys_dir, *evt_dir; > > + struct dirent *sys_dirent, *evt_dirent; > > + char evt_path[MAXPATHLEN]; > > + char *dir_path; > > + char **evt_list = NULL; > > + unsigned int evt_i = 0, evt_num = 0; > > + bool evt_num_known = false; > > + > > +restart: > > + sys_dir = tracing_events__opendir(); > > + if (!sys_dir) > > + return; > > + > > + if (evt_num_known) { > > + evt_list = zalloc(sizeof(char *) * evt_num); > > + if (!evt_list) > > + goto out_close_sys_dir; > > + } > > + > > + for_each_subsystem(sys_dir, sys_dirent) { > > + if (subsys_glob != NULL && > > + !strglobmatch(sys_dirent->d_name, subsys_glob)) > > + continue; > > + > > + dir_path = get_events_file(sys_dirent->d_name); > > + if (!dir_path) > > + continue; > > + evt_dir = opendir(dir_path); > > + if (!evt_dir) > > + goto next; > > + > > + for_each_event(dir_path, evt_dir, evt_dirent) { > > + if (event_glob != NULL && > > + !strglobmatch(evt_dirent->d_name, event_glob)) > > + continue; > > + > > + if (!evt_num_known) { > > + evt_num++; > > + continue; > > + } > > + > > + snprintf(evt_path, MAXPATHLEN, "%s:%s", > > + sys_dirent->d_name, evt_dirent->d_name); > > + > > + evt_list[evt_i] = strdup(evt_path); > > + if (evt_list[evt_i] == NULL) { > > + put_events_file(dir_path); > > + goto out_close_evt_dir; > > + } > > + evt_i++; > > + } > > + closedir(evt_dir); > > +next: > > + put_events_file(dir_path); > > + } > > + closedir(sys_dir); > > + > > + if (!evt_num_known) { > > + evt_num_known = true; > > + goto restart; > > + } > > + qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > + evt_i = 0; > > + while (evt_i < evt_num) { > > + if (name_only) { > > + printf("%s ", evt_list[evt_i++]); > > + continue; > > + } > > + printf(" %-50s [%s]\n", evt_list[evt_i++], > > + event_type_descriptors[PERF_TYPE_TRACEPOINT]); > > + } > > + if (evt_num && pager_in_use()) > > + printf("\n"); > > + > > +out_free: > > + evt_num = evt_i; > > + for (evt_i = 0; evt_i < evt_num; evt_i++) > > + zfree(&evt_list[evt_i]); > > + zfree(&evt_list); > > + return; > > + > > +out_close_evt_dir: > > + closedir(evt_dir); > > +out_close_sys_dir: > > + closedir(sys_dir); > > + > > + printf("FATAL: not enough memory to print %s\n", > > + event_type_descriptors[PERF_TYPE_TRACEPOINT]); > > + if (evt_list) > > + goto out_free; > > +} > > + > > +void print_sdt_events(const char *subsys_glob, const char *event_glob, > > + bool name_only) > > +{ > > + struct probe_cache *pcache; > > + struct probe_cache_entry *ent; > > + struct strlist *bidlist, *sdtlist; > > + struct strlist_config cfg = {.dont_dupstr = true}; > > + struct str_node *nd, *nd2; > > + char *buf, *path, *ptr = NULL; > > + bool show_detail = false; > > + int ret; > > + > > + sdtlist = strlist__new(NULL, &cfg); > > + if (!sdtlist) { > > + pr_debug("Failed to allocate new strlist for SDT\n"); > > + return; > > + } > > + bidlist = build_id_cache__list_all(true); > > + if (!bidlist) { > > + pr_debug("Failed to get buildids: %d\n", errno); > > + return; > > + } > > + strlist__for_each_entry(nd, bidlist) { > > + pcache = probe_cache__new(nd->s, NULL); > > + if (!pcache) > > + continue; > > + list_for_each_entry(ent, &pcache->entries, node) { > > + if (!ent->sdt) > > + continue; > > + if (subsys_glob && > > + !strglobmatch(ent->pev.group, subsys_glob)) > > + continue; > > + if (event_glob && > > + !strglobmatch(ent->pev.event, event_glob)) > > + continue; > > + ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, > > + ent->pev.event, nd->s); > > + if (ret > 0) > > + strlist__add(sdtlist, buf); > > + } > > + probe_cache__delete(pcache); > > + } > > + strlist__delete(bidlist); > > + > > + strlist__for_each_entry(nd, sdtlist) { > > + buf = strchr(nd->s, '@'); > > + if (buf) > > + *(buf++) = '\0'; > > + if (name_only) { > > + printf("%s ", nd->s); > > + continue; > > + } > > + nd2 = strlist__next(nd); > > + if (nd2) { > > + ptr = strchr(nd2->s, '@'); > > + if (ptr) > > + *ptr = '\0'; > > + if (strcmp(nd->s, nd2->s) == 0) > > + show_detail = true; > > + } > > + if (show_detail) { > > + path = build_id_cache__origname(buf); > > + ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, buf); > > + if (ret > 0) { > > + printf(" %-50s [%s]\n", buf, "SDT event"); > > + free(buf); > > + } > > + free(path); > > + } else > > + printf(" %-50s [%s]\n", nd->s, "SDT event"); > > + if (nd2) { > > + if (strcmp(nd->s, nd2->s) != 0) > > + show_detail = false; > > + if (ptr) > > + *ptr = '@'; > > + } > > + } > > + strlist__delete(sdtlist); > > +} > > + > > +static bool is_event_supported(u8 type, unsigned int config) > > +{ > > + bool ret = true; > > + int open_return; > > + struct evsel *evsel; > > + struct perf_event_attr attr = { > > + .type = type, > > + .config = config, > > + .disabled = 1, > > + }; > > + struct perf_thread_map *tmap = thread_map__new_by_tid(0); > > + > > + if (tmap == NULL) > > + return false; > > + > > + evsel = evsel__new(&attr); > > + if (evsel) { > > + open_return = evsel__open(evsel, NULL, tmap); > > + ret = open_return >= 0; > > + > > + if (open_return == -EACCES) { > > + /* > > + * This happens if the paranoid value > > + * /proc/sys/kernel/perf_event_paranoid is set to 2 > > + * Re-run with exclude_kernel set; we don't do that > > + * by default as some ARM machines do not support it. > > + * > > + */ > > + evsel->core.attr.exclude_kernel = 1; > > + ret = evsel__open(evsel, NULL, tmap) >= 0; > > + } > > + evsel__delete(evsel); > > + } > > + > > + perf_thread_map__put(tmap); > > + return ret; > > +} > > + > > +int print_hwcache_events(const char *event_glob, bool name_only) > > +{ > > + unsigned int type, op, i, evt_i = 0, evt_num = 0; > > + char name[64]; > > + char **evt_list = NULL; > > + bool evt_num_known = false; > > + > > +restart: > > + if (evt_num_known) { > > + evt_list = zalloc(sizeof(char *) * evt_num); > > + if (!evt_list) > > + goto out_enomem; > > + } > > + > > + for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { > > + for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { > > + /* skip invalid cache type */ > > + if (!evsel__is_cache_op_valid(type, op)) > > + continue; > > + > > + for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { > > + __evsel__hw_cache_type_op_res_name(type, op, i, name, sizeof(name)); > > + if (event_glob != NULL && !strglobmatch(name, event_glob)) > > + continue; > > + > > + if (!is_event_supported(PERF_TYPE_HW_CACHE, > > + type | (op << 8) | (i << 16))) > > + continue; > > + > > + if (!evt_num_known) { > > + evt_num++; > > + continue; > > + } > > + > > + evt_list[evt_i] = strdup(name); > > + if (evt_list[evt_i] == NULL) > > + goto out_enomem; > > + evt_i++; > > + } > > + } > > + } > > + > > + if (!evt_num_known) { > > + evt_num_known = true; > > + goto restart; > > + } > > + qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > + evt_i = 0; > > + while (evt_i < evt_num) { > > + if (name_only) { > > + printf("%s ", evt_list[evt_i++]); > > + continue; > > + } > > + printf(" %-50s [%s]\n", evt_list[evt_i++], > > + event_type_descriptors[PERF_TYPE_HW_CACHE]); > > + } > > + if (evt_num && pager_in_use()) > > + printf("\n"); > > + > > +out_free: > > + evt_num = evt_i; > > + for (evt_i = 0; evt_i < evt_num; evt_i++) > > + zfree(&evt_list[evt_i]); > > + zfree(&evt_list); > > + return evt_num; > > + > > +out_enomem: > > + printf("FATAL: not enough memory to print %s\n", event_type_descriptors[PERF_TYPE_HW_CACHE]); > > + if (evt_list) > > + goto out_free; > > + return evt_num; > > +} > > + > > +static void print_tool_event(const char *name, const char *event_glob, > > + bool name_only) > > +{ > > + if (event_glob && !strglobmatch(name, event_glob)) > > + return; > > + if (name_only) > > + printf("%s ", name); > > + else > > + printf(" %-50s [%s]\n", name, "Tool event"); > > + > > +} > > + > > +void print_tool_events(const char *event_glob, bool name_only) > > +{ > > + print_tool_event("duration_time", event_glob, name_only); > > + if (pager_in_use()) > > + printf("\n"); > > +} > > + > > +void print_symbol_events(const char *event_glob, unsigned int type, > > + struct event_symbol *syms, unsigned int max, > > + bool name_only) > > +{ > > + unsigned int i, evt_i = 0, evt_num = 0; > > + char name[MAX_NAME_LEN]; > > + char **evt_list = NULL; > > + bool evt_num_known = false; > > + > > +restart: > > + if (evt_num_known) { > > + evt_list = zalloc(sizeof(char *) * evt_num); > > + if (!evt_list) > > + goto out_enomem; > > + syms -= max; > > + } > > + > > + for (i = 0; i < max; i++, syms++) { > > + > > + if (event_glob != NULL && syms->symbol != NULL && > > + !(strglobmatch(syms->symbol, event_glob) || > > + (syms->alias && strglobmatch(syms->alias, event_glob)))) > > + continue; > > + > > + if (!is_event_supported(type, i)) > > + continue; > > + > > + if (!evt_num_known) { > > + evt_num++; > > + continue; > > + } > > + > > + if (!name_only && strlen(syms->alias)) > > + snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); > > + else > > + strlcpy(name, syms->symbol, MAX_NAME_LEN); > > + > > + evt_list[evt_i] = strdup(name); > > + if (evt_list[evt_i] == NULL) > > + goto out_enomem; > > + evt_i++; > > + } > > + > > + if (!evt_num_known) { > > + evt_num_known = true; > > + goto restart; > > + } > > + qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > + evt_i = 0; > > + while (evt_i < evt_num) { > > + if (name_only) { > > + printf("%s ", evt_list[evt_i++]); > > + continue; > > + } > > + printf(" %-50s [%s]\n", evt_list[evt_i++], event_type_descriptors[type]); > > + } > > + if (evt_num && pager_in_use()) > > + printf("\n"); > > + > > +out_free: > > + evt_num = evt_i; > > + for (evt_i = 0; evt_i < evt_num; evt_i++) > > + zfree(&evt_list[evt_i]); > > + zfree(&evt_list); > > + return; > > + > > +out_enomem: > > + printf("FATAL: not enough memory to print %s\n", event_type_descriptors[type]); > > + if (evt_list) > > + goto out_free; > > +} > > + > > +/* > > + * Print the help text for the event symbols: > > + */ > > +void print_events(const char *event_glob, bool name_only, bool quiet_flag, > > + bool long_desc, bool details_flag, bool deprecated) > > +{ > > + print_symbol_events(event_glob, PERF_TYPE_HARDWARE, > > + event_symbols_hw, PERF_COUNT_HW_MAX, name_only); > > + > > + print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, > > + event_symbols_sw, PERF_COUNT_SW_MAX, name_only); > > + print_tool_events(event_glob, name_only); > > + > > + print_hwcache_events(event_glob, name_only); > > + > > + print_pmu_events(event_glob, name_only, quiet_flag, long_desc, > > + details_flag, deprecated); > > + > > + if (event_glob != NULL) > > + return; > > + > > + if (!name_only) { > > + printf(" %-50s [%s]\n", > > + "rNNN", > > + event_type_descriptors[PERF_TYPE_RAW]); > > + printf(" %-50s [%s]\n", > > + "cpu/t1=v1[,t2=v2,t3 ...]/modifier", > > + event_type_descriptors[PERF_TYPE_RAW]); > > + if (pager_in_use()) > > + printf(" (see 'man perf-list' on how to encode it)\n\n"); > > + > > + printf(" %-50s [%s]\n", > > + "mem:<addr>[/len][:access]", > > + event_type_descriptors[PERF_TYPE_BREAKPOINT]); > > + if (pager_in_use()) > > + printf("\n"); > > + } > > + > > + print_tracepoint_events(NULL, NULL, name_only); > > + > > + print_sdt_events(NULL, NULL, name_only); > > + > > + metricgroup__print(true, true, NULL, name_only, details_flag); > > + > > + print_libpfm_events(name_only, long_desc); > > +} > > diff --git a/tools/perf/util/print-events.h b/tools/perf/util/print-events.h > > new file mode 100644 > > index 000000000000..cf64e8129c1b > > --- /dev/null > > +++ b/tools/perf/util/print-events.h > > @@ -0,0 +1,21 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +#ifndef __PERF_PRINT_EVENTS_H > > +#define __PERF_PRINT_EVENTS_H > > + > > +#include <stdbool.h> > > + > > +struct event_symbol; > > + > > +void print_events(const char *event_glob, bool name_only, bool quiet, > > + bool long_desc, bool details_flag, bool deprecated); > > +int print_hwcache_events(const char *event_glob, bool name_only); > > +void print_sdt_events(const char *subsys_glob, const char *event_glob, > > + bool name_only); > > +void print_symbol_events(const char *event_glob, unsigned int type, > > + struct event_symbol *syms, unsigned int max, > > + bool name_only); > > +void print_tool_events(const char *event_glob, bool name_only); > > +void print_tracepoint_events(const char *subsys_glob, const char *event_glob, > > + bool name_only); > > + > > +#endif /* __PERF_PRINT_EVENTS_H */ > > diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c > > index a65f65d0857e..fbc6d14aabbb 100644 > > --- a/tools/perf/util/trace-event-info.c > > +++ b/tools/perf/util/trace-event-info.c > > @@ -19,16 +19,24 @@ > > #include <linux/kernel.h> > > #include <linux/zalloc.h> > > #include <internal/lib.h> // page_size > > +#include <sys/param.h> > > > > #include "trace-event.h" > > +#include "tracepoint.h" > > #include <api/fs/tracing_path.h> > > #include "evsel.h" > > #include "debug.h" > > > > #define VERSION "0.6" > > +#define MAX_EVENT_LENGTH 512 > > > > static int output_fd; > > > > +struct tracepoint_path { > > + char *system; > > + char *name; > > + struct tracepoint_path *next; > > +}; > > > > int bigendian(void) > > { > > @@ -400,6 +408,92 @@ put_tracepoints_path(struct tracepoint_path *tps) > > } > > } > > > > +static struct tracepoint_path *tracepoint_id_to_path(u64 config) > > +{ > > + struct tracepoint_path *path = NULL; > > + DIR *sys_dir, *evt_dir; > > + struct dirent *sys_dirent, *evt_dirent; > > + char id_buf[24]; > > + int fd; > > + u64 id; > > + char evt_path[MAXPATHLEN]; > > + char *dir_path; > > + > > + sys_dir = tracing_events__opendir(); > > + if (!sys_dir) > > + return NULL; > > + > > + for_each_subsystem(sys_dir, sys_dirent) { > > + dir_path = get_events_file(sys_dirent->d_name); > > + if (!dir_path) > > + continue; > > + evt_dir = opendir(dir_path); > > + if (!evt_dir) > > + goto next; > > + > > + for_each_event(dir_path, evt_dir, evt_dirent) { > > + > > + scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, > > + evt_dirent->d_name); > > + fd = open(evt_path, O_RDONLY); > > + if (fd < 0) > > + continue; > > + if (read(fd, id_buf, sizeof(id_buf)) < 0) { > > + close(fd); > > + continue; > > + } > > + close(fd); > > + id = atoll(id_buf); > > + if (id == config) { > > + put_events_file(dir_path); > > + closedir(evt_dir); > > + closedir(sys_dir); > > + path = zalloc(sizeof(*path)); > > + if (!path) > > + return NULL; > > + if (asprintf(&path->system, "%.*s", MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { > > + free(path); > > + return NULL; > > + } > > + if (asprintf(&path->name, "%.*s", MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { > > + zfree(&path->system); > > + free(path); > > + return NULL; > > + } > > + return path; > > + } > > + } > > + closedir(evt_dir); > > +next: > > + put_events_file(dir_path); > > + } > > + > > + closedir(sys_dir); > > + return NULL; > > +} > > + > > +static struct tracepoint_path *tracepoint_name_to_path(const char *name) > > +{ > > + struct tracepoint_path *path = zalloc(sizeof(*path)); > > + char *str = strchr(name, ':'); > > + > > + if (path == NULL || str == NULL) { > > + free(path); > > + return NULL; > > + } > > + > > + path->system = strndup(name, str - name); > > + path->name = strdup(str+1); > > + > > + if (path->system == NULL || path->name == NULL) { > > + zfree(&path->system); > > + zfree(&path->name); > > + zfree(&path); > > + } > > + > > + return path; > > +} > > + > > static struct tracepoint_path * > > get_tracepoints_path(struct list_head *pattrs) > > { > > diff --git a/tools/perf/util/tracepoint.c b/tools/perf/util/tracepoint.c > > new file mode 100644 > > index 000000000000..89ef56c43311 > > --- /dev/null > > +++ b/tools/perf/util/tracepoint.c > > @@ -0,0 +1,63 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +#include "tracepoint.h" > > + > > +#include <errno.h> > > +#include <fcntl.h> > > +#include <stdio.h> > > +#include <sys/param.h> > > +#include <unistd.h> > > + > > +#include <api/fs/tracing_path.h> > > + > > +int tp_event_has_id(const char *dir_path, struct dirent *evt_dir) > > +{ > > + char evt_path[MAXPATHLEN]; > > + int fd; > > + > > + snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, evt_dir->d_name); > > + fd = open(evt_path, O_RDONLY); > > + if (fd < 0) > > + return -EINVAL; > > + close(fd); > > + > > + return 0; > > +} > > + > > +/* > > + * Check whether event is in <debugfs_mount_point>/tracing/events > > + */ > > +int is_valid_tracepoint(const char *event_string) > > +{ > > + DIR *sys_dir, *evt_dir; > > + struct dirent *sys_dirent, *evt_dirent; > > + char evt_path[MAXPATHLEN]; > > + char *dir_path; > > + > > + sys_dir = tracing_events__opendir(); > > + if (!sys_dir) > > + return 0; > > + > > + for_each_subsystem(sys_dir, sys_dirent) { > > + dir_path = get_events_file(sys_dirent->d_name); > > + if (!dir_path) > > + continue; > > + evt_dir = opendir(dir_path); > > + if (!evt_dir) > > + goto next; > > + > > + for_each_event(dir_path, evt_dir, evt_dirent) { > > + snprintf(evt_path, MAXPATHLEN, "%s:%s", > > + sys_dirent->d_name, evt_dirent->d_name); > > + if (!strcmp(evt_path, event_string)) { > > + closedir(evt_dir); > > + closedir(sys_dir); > > + return 1; > > + } > > + } > > + closedir(evt_dir); > > +next: > > + put_events_file(dir_path); > > + } > > + closedir(sys_dir); > > + return 0; > > +} > > diff --git a/tools/perf/util/tracepoint.h b/tools/perf/util/tracepoint.h > > new file mode 100644 > > index 000000000000..c4a110fe87d7 > > --- /dev/null > > +++ b/tools/perf/util/tracepoint.h > > @@ -0,0 +1,25 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > +#ifndef __PERF_TRACEPOINT_H > > +#define __PERF_TRACEPOINT_H > > + > > +#include <dirent.h> > > +#include <string.h> > > + > > +int tp_event_has_id(const char *dir_path, struct dirent *evt_dir); > > + > > +#define for_each_event(dir_path, evt_dir, evt_dirent) \ > > + while ((evt_dirent = readdir(evt_dir)) != NULL) \ > > + if (evt_dirent->d_type == DT_DIR && \ > > + (strcmp(evt_dirent->d_name, ".")) && \ > > + (strcmp(evt_dirent->d_name, "..")) && \ > > + (!tp_event_has_id(dir_path, evt_dirent))) > > + > > +#define for_each_subsystem(sys_dir, sys_dirent) \ > > + while ((sys_dirent = readdir(sys_dir)) != NULL) \ > > + if (sys_dirent->d_type == DT_DIR && \ > > + (strcmp(sys_dirent->d_name, ".")) && \ > > + (strcmp(sys_dirent->d_name, ".."))) > > + > > +int is_valid_tracepoint(const char *event_string); > > + > > +#endif /* __PERF_TRACEPOINT_H */ > > -- > > 2.30.0.365.g02bc693789-goog > > > > -- > > - Arnaldo ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: <CAP-5=fVFeT6YtXJGHX0OC1BCa121bTC+ER7XDVO2g5rr8DYfDw@mail.gmail.com>]
* Re: [PATCH 2/2] perf parse-events: Break out tracepoint and printing. [not found] ` <CAP-5=fVFeT6YtXJGHX0OC1BCa121bTC+ER7XDVO2g5rr8DYfDw@mail.gmail.com> @ 2021-02-03 20:50 ` Arnaldo Carvalho de Melo 2021-02-04 0:58 ` Arnaldo Carvalho de Melo 0 siblings, 1 reply; 8+ messages in thread From: Arnaldo Carvalho de Melo @ 2021-02-03 20:50 UTC (permalink / raw) To: Ian Rogers Cc: Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim, LKML, Stephane Eranian Em Wed, Feb 03, 2021 at 10:38:41AM -0800, Ian Rogers escreveu: > On Wed, Feb 3, 2021 at 8:21 AM Arnaldo Carvalho de Melo <acme@kernel.org> > wrote: > > > Em Tue, Feb 02, 2021 at 09:26:59PM -0800, Ian Rogers escreveu: > > > Move print_*_events functions out of parse-events.c into a new > > > print-events.c. Move tracepoint code into tracepoint.c or > > > trace-event-info.c (sole user). This reduces the dependencies of > > > parse-events.c and makes it more amenable to being a library in the > > > future. > > > Remove some unnecessary definitions from parse-events.h. Fix a > > > checkpatch.pl warning on using unsigned rather than unsigned int. > > > > Thanks, applied. > > > > Wow, cool :-) I wasn't sure about the macros in the headers. Are you > staging these patches before pushing to your perf/core or using > tmp.perf/core ? I know you mentioned a different approach. When I look at: > > https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/ > > I don't see anything newer than 9 days. Right, I'm collecting some more patches, will do build tests and push, till then, lemme push tmp.perf/core with what I have. > Thanks, > Ian > > - Arnaldo > > > > > > > Signed-off-by: Ian Rogers <irogers@google.com> > > > --- > > > tools/perf/builtin-list.c | 2 +- > > > tools/perf/builtin-lock.c | 1 + > > > tools/perf/builtin-timechart.c | 1 + > > > tools/perf/builtin-trace.c | 1 + > > > tools/perf/util/Build | 2 + > > > tools/perf/util/parse-events.c | 620 +---------------------------- > > > tools/perf/util/parse-events.h | 29 -- > > > tools/perf/util/print-events.c | 472 ++++++++++++++++++++++ > > > tools/perf/util/print-events.h | 21 + > > > tools/perf/util/trace-event-info.c | 94 +++++ > > > tools/perf/util/tracepoint.c | 63 +++ > > > tools/perf/util/tracepoint.h | 25 ++ > > > 12 files changed, 687 insertions(+), 644 deletions(-) > > > create mode 100644 tools/perf/util/print-events.c > > > create mode 100644 tools/perf/util/print-events.h > > > create mode 100644 tools/perf/util/tracepoint.c > > > create mode 100644 tools/perf/util/tracepoint.h > > > > > > diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c > > > index 10ab5e40a34f..91327a321c36 100644 > > > --- a/tools/perf/builtin-list.c > > > +++ b/tools/perf/builtin-list.c > > > @@ -10,7 +10,7 @@ > > > */ > > > #include "builtin.h" > > > > > > -#include "util/parse-events.h" > > > +#include "util/print-events.h" > > > #include "util/pmu.h" > > > #include "util/debug.h" > > > #include "util/metricgroup.h" > > > diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c > > > index a2f1e53f37a7..486123cb106e 100644 > > > --- a/tools/perf/builtin-lock.c > > > +++ b/tools/perf/builtin-lock.c > > > @@ -13,6 +13,7 @@ > > > #include <subcmd/pager.h> > > > #include <subcmd/parse-options.h> > > > #include "util/trace-event.h" > > > +#include "util/tracepoint.h" > > > > > > #include "util/debug.h" > > > #include "util/session.h" > > > diff --git a/tools/perf/builtin-timechart.c > > b/tools/perf/builtin-timechart.c > > > index 4e380e7b5230..cdebcf26f408 100644 > > > --- a/tools/perf/builtin-timechart.c > > > +++ b/tools/perf/builtin-timechart.c > > > @@ -35,6 +35,7 @@ > > > #include "util/tool.h" > > > #include "util/data.h" > > > #include "util/debug.h" > > > +#include "util/tracepoint.h" > > > #include <linux/err.h> > > > > > > #ifdef LACKS_OPEN_MEMSTREAM_PROTOTYPE > > > diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c > > > index 85b6a46e85b6..b3b9fa1c7731 100644 > > > --- a/tools/perf/builtin-trace.c > > > +++ b/tools/perf/builtin-trace.c > > > @@ -53,6 +53,7 @@ > > > #include "trace-event.h" > > > #include "util/parse-events.h" > > > #include "util/bpf-loader.h" > > > +#include "util/tracepoint.h" > > > #include "callchain.h" > > > #include "print_binary.h" > > > #include "string2.h" > > > diff --git a/tools/perf/util/Build b/tools/perf/util/Build > > > index 188521f34347..c2c9f3f490e8 100644 > > > --- a/tools/perf/util/Build > > > +++ b/tools/perf/util/Build > > > @@ -23,6 +23,8 @@ perf-y += llvm-utils.o > > > perf-y += mmap.o > > > perf-y += memswap.o > > > perf-y += parse-events.o > > > +perf-y += print-events.o > > > +perf-y += tracepoint.o > > > perf-y += perf_regs.o > > > perf-y += path.o > > > perf-y += print_binary.o > > > diff --git a/tools/perf/util/parse-events.c > > b/tools/perf/util/parse-events.c > > > index 42c84adeb2fb..5d5ebb700ef2 100644 > > > --- a/tools/perf/util/parse-events.c > > > +++ b/tools/perf/util/parse-events.c > > > @@ -5,42 +5,34 @@ > > > #include <dirent.h> > > > #include <errno.h> > > > #include <sys/ioctl.h> > > > -#include <sys/types.h> > > > -#include <sys/stat.h> > > > -#include <fcntl.h> > > > #include <sys/param.h> > > > #include "term.h" > > > -#include "build-id.h" > > > #include "evlist.h" > > > #include "evsel.h" > > > -#include <subcmd/pager.h> > > > #include <subcmd/parse-options.h> > > > #include "parse-events.h" > > > -#include <subcmd/exec-cmd.h> > > > #include "string2.h" > > > -#include "strlist.h" > > > -#include "symbol.h" > > > -#include "header.h" > > > #include "bpf-loader.h" > > > #include "debug.h" > > > #include <api/fs/tracing_path.h> > > > #include <perf/cpumap.h> > > > #include "parse-events-bison.h" > > > -#define YY_EXTRA_TYPE void* > > > #include "parse-events-flex.h" > > > #include "pmu.h" > > > -#include "thread_map.h" > > > -#include "probe-file.h" > > > #include "asm/bug.h" > > > #include "util/parse-branch-options.h" > > > -#include "metricgroup.h" > > > #include "util/evsel_config.h" > > > #include "util/event.h" > > > -#include "util/pfm.h" > > > #include "perf.h" > > > +#include "tracepoint.h" > > > > > > #define MAX_NAME_LEN 100 > > > > > > +struct perf_pmu_event_symbol { > > > + char *symbol; > > > + enum perf_pmu_event_symbol_type type; > > > +}; > > > + > > > #ifdef PARSER_DEBUG > > > extern int parse_events_debug; > > > #endif > > > @@ -155,35 +147,6 @@ struct event_symbol > > event_symbols_sw[PERF_COUNT_SW_MAX] = { > > > #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, > > TYPE) > > > #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, > > EVENT) > > > > > > -#define for_each_subsystem(sys_dir, sys_dirent) \ > > > - while ((sys_dirent = readdir(sys_dir)) != NULL) \ > > > - if (sys_dirent->d_type == DT_DIR && \ > > > - (strcmp(sys_dirent->d_name, ".")) && \ > > > - (strcmp(sys_dirent->d_name, ".."))) > > > - > > > -static int tp_event_has_id(const char *dir_path, struct dirent *evt_dir) > > > -{ > > > - char evt_path[MAXPATHLEN]; > > > - int fd; > > > - > > > - snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, > > evt_dir->d_name); > > > - fd = open(evt_path, O_RDONLY); > > > - if (fd < 0) > > > - return -EINVAL; > > > - close(fd); > > > - > > > - return 0; > > > -} > > > - > > > -#define for_each_event(dir_path, evt_dir, evt_dirent) \ > > > - while ((evt_dirent = readdir(evt_dir)) != NULL) \ > > > - if (evt_dirent->d_type == DT_DIR && \ > > > - (strcmp(evt_dirent->d_name, ".")) && \ > > > - (strcmp(evt_dirent->d_name, "..")) && \ > > > - (!tp_event_has_id(dir_path, evt_dirent))) > > > - > > > -#define MAX_EVENT_LENGTH 512 > > > - > > > void parse_events__handle_error(struct parse_events_error *err, int idx, > > > char *str, char *help) > > > { > > > @@ -217,92 +180,6 @@ void parse_events__handle_error(struct > > parse_events_error *err, int idx, > > > err->num_errors++; > > > } > > > > > > -struct tracepoint_path *tracepoint_id_to_path(u64 config) > > > -{ > > > - struct tracepoint_path *path = NULL; > > > - DIR *sys_dir, *evt_dir; > > > - struct dirent *sys_dirent, *evt_dirent; > > > - char id_buf[24]; > > > - int fd; > > > - u64 id; > > > - char evt_path[MAXPATHLEN]; > > > - char *dir_path; > > > - > > > - sys_dir = tracing_events__opendir(); > > > - if (!sys_dir) > > > - return NULL; > > > - > > > - for_each_subsystem(sys_dir, sys_dirent) { > > > - dir_path = get_events_file(sys_dirent->d_name); > > > - if (!dir_path) > > > - continue; > > > - evt_dir = opendir(dir_path); > > > - if (!evt_dir) > > > - goto next; > > > - > > > - for_each_event(dir_path, evt_dir, evt_dirent) { > > > - > > > - scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", > > dir_path, > > > - evt_dirent->d_name); > > > - fd = open(evt_path, O_RDONLY); > > > - if (fd < 0) > > > - continue; > > > - if (read(fd, id_buf, sizeof(id_buf)) < 0) { > > > - close(fd); > > > - continue; > > > - } > > > - close(fd); > > > - id = atoll(id_buf); > > > - if (id == config) { > > > - put_events_file(dir_path); > > > - closedir(evt_dir); > > > - closedir(sys_dir); > > > - path = zalloc(sizeof(*path)); > > > - if (!path) > > > - return NULL; > > > - if (asprintf(&path->system, "%.*s", > > MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { > > > - free(path); > > > - return NULL; > > > - } > > > - if (asprintf(&path->name, "%.*s", > > MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { > > > - zfree(&path->system); > > > - free(path); > > > - return NULL; > > > - } > > > - return path; > > > - } > > > - } > > > - closedir(evt_dir); > > > -next: > > > - put_events_file(dir_path); > > > - } > > > - > > > - closedir(sys_dir); > > > - return NULL; > > > -} > > > - > > > -struct tracepoint_path *tracepoint_name_to_path(const char *name) > > > -{ > > > - struct tracepoint_path *path = zalloc(sizeof(*path)); > > > - char *str = strchr(name, ':'); > > > - > > > - if (path == NULL || str == NULL) { > > > - free(path); > > > - return NULL; > > > - } > > > - > > > - path->system = strndup(name, str - name); > > > - path->name = strdup(str+1); > > > - > > > - if (path->system == NULL || path->name == NULL) { > > > - zfree(&path->system); > > > - zfree(&path->name); > > > - zfree(&path); > > > - } > > > - > > > - return path; > > > -} > > > - > > > const char *event_type(int type) > > > { > > > switch (type) { > > > @@ -2451,491 +2328,6 @@ int exclude_perf(const struct option *opt, > > > NULL); > > > } > > > > > > -static const char * const event_type_descriptors[] = { > > > - "Hardware event", > > > - "Software event", > > > - "Tracepoint event", > > > - "Hardware cache event", > > > - "Raw hardware event descriptor", > > > - "Hardware breakpoint", > > > -}; > > > - > > > -static int cmp_string(const void *a, const void *b) > > > -{ > > > - const char * const *as = a; > > > - const char * const *bs = b; > > > - > > > - return strcmp(*as, *bs); > > > -} > > > - > > > -/* > > > - * Print the events from <debugfs_mount_point>/tracing/events > > > - */ > > > - > > > -void print_tracepoint_events(const char *subsys_glob, const char > > *event_glob, > > > - bool name_only) > > > -{ > > > - DIR *sys_dir, *evt_dir; > > > - struct dirent *sys_dirent, *evt_dirent; > > > - char evt_path[MAXPATHLEN]; > > > - char *dir_path; > > > - char **evt_list = NULL; > > > - unsigned int evt_i = 0, evt_num = 0; > > > - bool evt_num_known = false; > > > - > > > -restart: > > > - sys_dir = tracing_events__opendir(); > > > - if (!sys_dir) > > > - return; > > > - > > > - if (evt_num_known) { > > > - evt_list = zalloc(sizeof(char *) * evt_num); > > > - if (!evt_list) > > > - goto out_close_sys_dir; > > > - } > > > - > > > - for_each_subsystem(sys_dir, sys_dirent) { > > > - if (subsys_glob != NULL && > > > - !strglobmatch(sys_dirent->d_name, subsys_glob)) > > > - continue; > > > - > > > - dir_path = get_events_file(sys_dirent->d_name); > > > - if (!dir_path) > > > - continue; > > > - evt_dir = opendir(dir_path); > > > - if (!evt_dir) > > > - goto next; > > > - > > > - for_each_event(dir_path, evt_dir, evt_dirent) { > > > - if (event_glob != NULL && > > > - !strglobmatch(evt_dirent->d_name, event_glob)) > > > - continue; > > > - > > > - if (!evt_num_known) { > > > - evt_num++; > > > - continue; > > > - } > > > - > > > - snprintf(evt_path, MAXPATHLEN, "%s:%s", > > > - sys_dirent->d_name, evt_dirent->d_name); > > > - > > > - evt_list[evt_i] = strdup(evt_path); > > > - if (evt_list[evt_i] == NULL) { > > > - put_events_file(dir_path); > > > - goto out_close_evt_dir; > > > - } > > > - evt_i++; > > > - } > > > - closedir(evt_dir); > > > -next: > > > - put_events_file(dir_path); > > > - } > > > - closedir(sys_dir); > > > - > > > - if (!evt_num_known) { > > > - evt_num_known = true; > > > - goto restart; > > > - } > > > - qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > > - evt_i = 0; > > > - while (evt_i < evt_num) { > > > - if (name_only) { > > > - printf("%s ", evt_list[evt_i++]); > > > - continue; > > > - } > > > - printf(" %-50s [%s]\n", evt_list[evt_i++], > > > - > > event_type_descriptors[PERF_TYPE_TRACEPOINT]); > > > - } > > > - if (evt_num && pager_in_use()) > > > - printf("\n"); > > > - > > > -out_free: > > > - evt_num = evt_i; > > > - for (evt_i = 0; evt_i < evt_num; evt_i++) > > > - zfree(&evt_list[evt_i]); > > > - zfree(&evt_list); > > > - return; > > > - > > > -out_close_evt_dir: > > > - closedir(evt_dir); > > > -out_close_sys_dir: > > > - closedir(sys_dir); > > > - > > > - printf("FATAL: not enough memory to print %s\n", > > > - event_type_descriptors[PERF_TYPE_TRACEPOINT]); > > > - if (evt_list) > > > - goto out_free; > > > -} > > > - > > > -/* > > > - * Check whether event is in <debugfs_mount_point>/tracing/events > > > - */ > > > - > > > -int is_valid_tracepoint(const char *event_string) > > > -{ > > > - DIR *sys_dir, *evt_dir; > > > - struct dirent *sys_dirent, *evt_dirent; > > > - char evt_path[MAXPATHLEN]; > > > - char *dir_path; > > > - > > > - sys_dir = tracing_events__opendir(); > > > - if (!sys_dir) > > > - return 0; > > > - > > > - for_each_subsystem(sys_dir, sys_dirent) { > > > - dir_path = get_events_file(sys_dirent->d_name); > > > - if (!dir_path) > > > - continue; > > > - evt_dir = opendir(dir_path); > > > - if (!evt_dir) > > > - goto next; > > > - > > > - for_each_event(dir_path, evt_dir, evt_dirent) { > > > - snprintf(evt_path, MAXPATHLEN, "%s:%s", > > > - sys_dirent->d_name, evt_dirent->d_name); > > > - if (!strcmp(evt_path, event_string)) { > > > - closedir(evt_dir); > > > - closedir(sys_dir); > > > - return 1; > > > - } > > > - } > > > - closedir(evt_dir); > > > -next: > > > - put_events_file(dir_path); > > > - } > > > - closedir(sys_dir); > > > - return 0; > > > -} > > > - > > > -static bool is_event_supported(u8 type, unsigned config) > > > -{ > > > - bool ret = true; > > > - int open_return; > > > - struct evsel *evsel; > > > - struct perf_event_attr attr = { > > > - .type = type, > > > - .config = config, > > > - .disabled = 1, > > > - }; > > > - struct perf_thread_map *tmap = thread_map__new_by_tid(0); > > > - > > > - if (tmap == NULL) > > > - return false; > > > - > > > - evsel = evsel__new(&attr); > > > - if (evsel) { > > > - open_return = evsel__open(evsel, NULL, tmap); > > > - ret = open_return >= 0; > > > - > > > - if (open_return == -EACCES) { > > > - /* > > > - * This happens if the paranoid value > > > - * /proc/sys/kernel/perf_event_paranoid is set to 2 > > > - * Re-run with exclude_kernel set; we don't do that > > > - * by default as some ARM machines do not support > > it. > > > - * > > > - */ > > > - evsel->core.attr.exclude_kernel = 1; > > > - ret = evsel__open(evsel, NULL, tmap) >= 0; > > > - } > > > - evsel__delete(evsel); > > > - } > > > - > > > - perf_thread_map__put(tmap); > > > - return ret; > > > -} > > > - > > > -void print_sdt_events(const char *subsys_glob, const char *event_glob, > > > - bool name_only) > > > -{ > > > - struct probe_cache *pcache; > > > - struct probe_cache_entry *ent; > > > - struct strlist *bidlist, *sdtlist; > > > - struct strlist_config cfg = {.dont_dupstr = true}; > > > - struct str_node *nd, *nd2; > > > - char *buf, *path, *ptr = NULL; > > > - bool show_detail = false; > > > - int ret; > > > - > > > - sdtlist = strlist__new(NULL, &cfg); > > > - if (!sdtlist) { > > > - pr_debug("Failed to allocate new strlist for SDT\n"); > > > - return; > > > - } > > > - bidlist = build_id_cache__list_all(true); > > > - if (!bidlist) { > > > - pr_debug("Failed to get buildids: %d\n", errno); > > > - return; > > > - } > > > - strlist__for_each_entry(nd, bidlist) { > > > - pcache = probe_cache__new(nd->s, NULL); > > > - if (!pcache) > > > - continue; > > > - list_for_each_entry(ent, &pcache->entries, node) { > > > - if (!ent->sdt) > > > - continue; > > > - if (subsys_glob && > > > - !strglobmatch(ent->pev.group, subsys_glob)) > > > - continue; > > > - if (event_glob && > > > - !strglobmatch(ent->pev.event, event_glob)) > > > - continue; > > > - ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, > > > - ent->pev.event, nd->s); > > > - if (ret > 0) > > > - strlist__add(sdtlist, buf); > > > - } > > > - probe_cache__delete(pcache); > > > - } > > > - strlist__delete(bidlist); > > > - > > > - strlist__for_each_entry(nd, sdtlist) { > > > - buf = strchr(nd->s, '@'); > > > - if (buf) > > > - *(buf++) = '\0'; > > > - if (name_only) { > > > - printf("%s ", nd->s); > > > - continue; > > > - } > > > - nd2 = strlist__next(nd); > > > - if (nd2) { > > > - ptr = strchr(nd2->s, '@'); > > > - if (ptr) > > > - *ptr = '\0'; > > > - if (strcmp(nd->s, nd2->s) == 0) > > > - show_detail = true; > > > - } > > > - if (show_detail) { > > > - path = build_id_cache__origname(buf); > > > - ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, > > buf); > > > - if (ret > 0) { > > > - printf(" %-50s [%s]\n", buf, "SDT event"); > > > - free(buf); > > > - } > > > - free(path); > > > - } else > > > - printf(" %-50s [%s]\n", nd->s, "SDT event"); > > > - if (nd2) { > > > - if (strcmp(nd->s, nd2->s) != 0) > > > - show_detail = false; > > > - if (ptr) > > > - *ptr = '@'; > > > - } > > > - } > > > - strlist__delete(sdtlist); > > > -} > > > - > > > -int print_hwcache_events(const char *event_glob, bool name_only) > > > -{ > > > - unsigned int type, op, i, evt_i = 0, evt_num = 0; > > > - char name[64]; > > > - char **evt_list = NULL; > > > - bool evt_num_known = false; > > > - > > > -restart: > > > - if (evt_num_known) { > > > - evt_list = zalloc(sizeof(char *) * evt_num); > > > - if (!evt_list) > > > - goto out_enomem; > > > - } > > > - > > > - for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { > > > - for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { > > > - /* skip invalid cache type */ > > > - if (!evsel__is_cache_op_valid(type, op)) > > > - continue; > > > - > > > - for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; > > i++) { > > > - __evsel__hw_cache_type_op_res_name(type, > > op, i, name, sizeof(name)); > > > - if (event_glob != NULL && > > !strglobmatch(name, event_glob)) > > > - continue; > > > - > > > - if (!is_event_supported(PERF_TYPE_HW_CACHE, > > > - type | (op << 8) | > > (i << 16))) > > > - continue; > > > - > > > - if (!evt_num_known) { > > > - evt_num++; > > > - continue; > > > - } > > > - > > > - evt_list[evt_i] = strdup(name); > > > - if (evt_list[evt_i] == NULL) > > > - goto out_enomem; > > > - evt_i++; > > > - } > > > - } > > > - } > > > - > > > - if (!evt_num_known) { > > > - evt_num_known = true; > > > - goto restart; > > > - } > > > - qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > > - evt_i = 0; > > > - while (evt_i < evt_num) { > > > - if (name_only) { > > > - printf("%s ", evt_list[evt_i++]); > > > - continue; > > > - } > > > - printf(" %-50s [%s]\n", evt_list[evt_i++], > > > - > > event_type_descriptors[PERF_TYPE_HW_CACHE]); > > > - } > > > - if (evt_num && pager_in_use()) > > > - printf("\n"); > > > - > > > -out_free: > > > - evt_num = evt_i; > > > - for (evt_i = 0; evt_i < evt_num; evt_i++) > > > - zfree(&evt_list[evt_i]); > > > - zfree(&evt_list); > > > - return evt_num; > > > - > > > -out_enomem: > > > - printf("FATAL: not enough memory to print %s\n", > > event_type_descriptors[PERF_TYPE_HW_CACHE]); > > > - if (evt_list) > > > - goto out_free; > > > - return evt_num; > > > -} > > > - > > > -static void print_tool_event(const char *name, const char *event_glob, > > > - bool name_only) > > > -{ > > > - if (event_glob && !strglobmatch(name, event_glob)) > > > - return; > > > - if (name_only) > > > - printf("%s ", name); > > > - else > > > - printf(" %-50s [%s]\n", name, "Tool event"); > > > - > > > -} > > > - > > > -void print_tool_events(const char *event_glob, bool name_only) > > > -{ > > > - print_tool_event("duration_time", event_glob, name_only); > > > - if (pager_in_use()) > > > - printf("\n"); > > > -} > > > - > > > -void print_symbol_events(const char *event_glob, unsigned type, > > > - struct event_symbol *syms, unsigned max, > > > - bool name_only) > > > -{ > > > - unsigned int i, evt_i = 0, evt_num = 0; > > > - char name[MAX_NAME_LEN]; > > > - char **evt_list = NULL; > > > - bool evt_num_known = false; > > > - > > > -restart: > > > - if (evt_num_known) { > > > - evt_list = zalloc(sizeof(char *) * evt_num); > > > - if (!evt_list) > > > - goto out_enomem; > > > - syms -= max; > > > - } > > > - > > > - for (i = 0; i < max; i++, syms++) { > > > - > > > - if (event_glob != NULL && syms->symbol != NULL && > > > - !(strglobmatch(syms->symbol, event_glob) || > > > - (syms->alias && strglobmatch(syms->alias, > > event_glob)))) > > > - continue; > > > - > > > - if (!is_event_supported(type, i)) > > > - continue; > > > - > > > - if (!evt_num_known) { > > > - evt_num++; > > > - continue; > > > - } > > > - > > > - if (!name_only && strlen(syms->alias)) > > > - snprintf(name, MAX_NAME_LEN, "%s OR %s", > > syms->symbol, syms->alias); > > > - else > > > - strlcpy(name, syms->symbol, MAX_NAME_LEN); > > > - > > > - evt_list[evt_i] = strdup(name); > > > - if (evt_list[evt_i] == NULL) > > > - goto out_enomem; > > > - evt_i++; > > > - } > > > - > > > - if (!evt_num_known) { > > > - evt_num_known = true; > > > - goto restart; > > > - } > > > - qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > > - evt_i = 0; > > > - while (evt_i < evt_num) { > > > - if (name_only) { > > > - printf("%s ", evt_list[evt_i++]); > > > - continue; > > > - } > > > - printf(" %-50s [%s]\n", evt_list[evt_i++], > > event_type_descriptors[type]); > > > - } > > > - if (evt_num && pager_in_use()) > > > - printf("\n"); > > > - > > > -out_free: > > > - evt_num = evt_i; > > > - for (evt_i = 0; evt_i < evt_num; evt_i++) > > > - zfree(&evt_list[evt_i]); > > > - zfree(&evt_list); > > > - return; > > > - > > > -out_enomem: > > > - printf("FATAL: not enough memory to print %s\n", > > event_type_descriptors[type]); > > > - if (evt_list) > > > - goto out_free; > > > -} > > > - > > > -/* > > > - * Print the help text for the event symbols: > > > - */ > > > -void print_events(const char *event_glob, bool name_only, bool > > quiet_flag, > > > - bool long_desc, bool details_flag, bool deprecated) > > > -{ > > > - print_symbol_events(event_glob, PERF_TYPE_HARDWARE, > > > - event_symbols_hw, PERF_COUNT_HW_MAX, > > name_only); > > > - > > > - print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, > > > - event_symbols_sw, PERF_COUNT_SW_MAX, > > name_only); > > > - print_tool_events(event_glob, name_only); > > > - > > > - print_hwcache_events(event_glob, name_only); > > > - > > > - print_pmu_events(event_glob, name_only, quiet_flag, long_desc, > > > - details_flag, deprecated); > > > - > > > - if (event_glob != NULL) > > > - return; > > > - > > > - if (!name_only) { > > > - printf(" %-50s [%s]\n", > > > - "rNNN", > > > - event_type_descriptors[PERF_TYPE_RAW]); > > > - printf(" %-50s [%s]\n", > > > - "cpu/t1=v1[,t2=v2,t3 ...]/modifier", > > > - event_type_descriptors[PERF_TYPE_RAW]); > > > - if (pager_in_use()) > > > - printf(" (see 'man perf-list' on how to encode > > it)\n\n"); > > > - > > > - printf(" %-50s [%s]\n", > > > - "mem:<addr>[/len][:access]", > > > - event_type_descriptors[PERF_TYPE_BREAKPOINT]); > > > - if (pager_in_use()) > > > - printf("\n"); > > > - } > > > - > > > - print_tracepoint_events(NULL, NULL, name_only); > > > - > > > - print_sdt_events(NULL, NULL, name_only); > > > - > > > - metricgroup__print(true, true, NULL, name_only, details_flag); > > > - > > > - print_libpfm_events(name_only, long_desc); > > > -} > > > - > > > int parse_events__is_hardcoded_term(struct parse_events_term *term) > > > { > > > return term->type_term != PARSE_EVENTS__TERM_TYPE_USER; > > > diff --git a/tools/perf/util/parse-events.h > > b/tools/perf/util/parse-events.h > > > index e80c9b74f2f2..7cea425e80f9 100644 > > > --- a/tools/perf/util/parse-events.h > > > +++ b/tools/perf/util/parse-events.h > > > @@ -11,7 +11,6 @@ > > > #include <linux/perf_event.h> > > > #include <string.h> > > > > > > -struct list_head; > > > struct evsel; > > > struct evlist; > > > struct parse_events_error; > > > @@ -19,14 +18,6 @@ struct parse_events_error; > > > struct option; > > > struct perf_pmu; > > > > > > -struct tracepoint_path { > > > - char *system; > > > - char *name; > > > - struct tracepoint_path *next; > > > -}; > > > - > > > -struct tracepoint_path *tracepoint_id_to_path(u64 config); > > > -struct tracepoint_path *tracepoint_name_to_path(const char *name); > > > bool have_tracepoints(struct list_head *evlist); > > > > > > const char *event_type(int type); > > > @@ -46,8 +37,6 @@ int parse_events_terms(struct list_head *terms, const > > char *str); > > > int parse_filter(const struct option *opt, const char *str, int unset); > > > int exclude_perf(const struct option *opt, const char *arg, int unset); > > > > > > -#define EVENTS_HELP_MAX (128*1024) > > > - > > > enum perf_pmu_event_symbol_type { > > > PMU_EVENT_SYMBOL_ERR, /* not a PMU EVENT */ > > > PMU_EVENT_SYMBOL, /* normal style PMU event */ > > > @@ -55,11 +44,6 @@ enum perf_pmu_event_symbol_type { > > > PMU_EVENT_SYMBOL_SUFFIX, /* suffix of pre-suf style event */ > > > }; > > > > > > -struct perf_pmu_event_symbol { > > > - char *symbol; > > > - enum perf_pmu_event_symbol_type type; > > > -}; > > > - > > > enum { > > > PARSE_EVENTS__TERM_TYPE_NUM, > > > PARSE_EVENTS__TERM_TYPE_STR, > > > @@ -216,8 +200,6 @@ void parse_events_update_lists(struct list_head > > *list_event, > > > void parse_events_evlist_error(struct parse_events_state *parse_state, > > > int idx, const char *str); > > > > > > -void print_events(const char *event_glob, bool name_only, bool quiet, > > > - bool long_desc, bool details_flag, bool deprecated); > > > > > > struct event_symbol { > > > const char *symbol; > > > @@ -225,18 +207,7 @@ struct event_symbol { > > > }; > > > extern struct event_symbol event_symbols_hw[]; > > > extern struct event_symbol event_symbols_sw[]; > > > -void print_symbol_events(const char *event_glob, unsigned type, > > > - struct event_symbol *syms, unsigned max, > > > - bool name_only); > > > -void print_tool_events(const char *event_glob, bool name_only); > > > -void print_tracepoint_events(const char *subsys_glob, const char > > *event_glob, > > > - bool name_only); > > > -int print_hwcache_events(const char *event_glob, bool name_only); > > > -void print_sdt_events(const char *subsys_glob, const char *event_glob, > > > - bool name_only); > > > -int is_valid_tracepoint(const char *event_string); > > > > > > -int valid_event_mount(const char *eventfs); > > > char *parse_events_formats_error_string(char *additional_terms); > > > > > > void parse_events_print_error(struct parse_events_error *err, > > > diff --git a/tools/perf/util/print-events.c > > b/tools/perf/util/print-events.c > > > new file mode 100644 > > > index 000000000000..584888353d13 > > > --- /dev/null > > > +++ b/tools/perf/util/print-events.c > > > @@ -0,0 +1,472 @@ > > > +// SPDX-License-Identifier: GPL-2.0 > > > +#include <dirent.h> > > > +#include <errno.h> > > > +#include <stdio.h> > > > +#include <stdlib.h> > > > +#include <string.h> > > > +#include <sys/param.h> > > > + > > > +#include <api/fs/tracing_path.h> > > > +#include <linux/perf_event.h> > > > +#include <linux/zalloc.h> > > > +#include <subcmd/pager.h> > > > + > > > +#include "build-id.h" > > > +#include "debug.h" > > > +#include "evsel.h" > > > +#include "metricgroup.h" > > > +#include "parse-events.h" > > > +#include "pmu.h" > > > +#include "print-events.h" > > > +#include "probe-file.h" > > > +#include "string2.h" > > > +#include "strlist.h" > > > +#include "thread_map.h" > > > +#include "tracepoint.h" > > > +#include "pfm.h" > > > + > > > +#define MAX_NAME_LEN 100 > > > + > > > +static int cmp_string(const void *a, const void *b) > > > +{ > > > + const char * const *as = a; > > > + const char * const *bs = b; > > > + > > > + return strcmp(*as, *bs); > > > +} > > > + > > > +static const char * const event_type_descriptors[] = { > > > + "Hardware event", > > > + "Software event", > > > + "Tracepoint event", > > > + "Hardware cache event", > > > + "Raw hardware event descriptor", > > > + "Hardware breakpoint", > > > +}; > > > + > > > +/* > > > + * Print the events from <debugfs_mount_point>/tracing/events > > > + */ > > > +void print_tracepoint_events(const char *subsys_glob, > > > + const char *event_glob, bool name_only) > > > +{ > > > + DIR *sys_dir, *evt_dir; > > > + struct dirent *sys_dirent, *evt_dirent; > > > + char evt_path[MAXPATHLEN]; > > > + char *dir_path; > > > + char **evt_list = NULL; > > > + unsigned int evt_i = 0, evt_num = 0; > > > + bool evt_num_known = false; > > > + > > > +restart: > > > + sys_dir = tracing_events__opendir(); > > > + if (!sys_dir) > > > + return; > > > + > > > + if (evt_num_known) { > > > + evt_list = zalloc(sizeof(char *) * evt_num); > > > + if (!evt_list) > > > + goto out_close_sys_dir; > > > + } > > > + > > > + for_each_subsystem(sys_dir, sys_dirent) { > > > + if (subsys_glob != NULL && > > > + !strglobmatch(sys_dirent->d_name, subsys_glob)) > > > + continue; > > > + > > > + dir_path = get_events_file(sys_dirent->d_name); > > > + if (!dir_path) > > > + continue; > > > + evt_dir = opendir(dir_path); > > > + if (!evt_dir) > > > + goto next; > > > + > > > + for_each_event(dir_path, evt_dir, evt_dirent) { > > > + if (event_glob != NULL && > > > + !strglobmatch(evt_dirent->d_name, event_glob)) > > > + continue; > > > + > > > + if (!evt_num_known) { > > > + evt_num++; > > > + continue; > > > + } > > > + > > > + snprintf(evt_path, MAXPATHLEN, "%s:%s", > > > + sys_dirent->d_name, evt_dirent->d_name); > > > + > > > + evt_list[evt_i] = strdup(evt_path); > > > + if (evt_list[evt_i] == NULL) { > > > + put_events_file(dir_path); > > > + goto out_close_evt_dir; > > > + } > > > + evt_i++; > > > + } > > > + closedir(evt_dir); > > > +next: > > > + put_events_file(dir_path); > > > + } > > > + closedir(sys_dir); > > > + > > > + if (!evt_num_known) { > > > + evt_num_known = true; > > > + goto restart; > > > + } > > > + qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > > + evt_i = 0; > > > + while (evt_i < evt_num) { > > > + if (name_only) { > > > + printf("%s ", evt_list[evt_i++]); > > > + continue; > > > + } > > > + printf(" %-50s [%s]\n", evt_list[evt_i++], > > > + > > event_type_descriptors[PERF_TYPE_TRACEPOINT]); > > > + } > > > + if (evt_num && pager_in_use()) > > > + printf("\n"); > > > + > > > +out_free: > > > + evt_num = evt_i; > > > + for (evt_i = 0; evt_i < evt_num; evt_i++) > > > + zfree(&evt_list[evt_i]); > > > + zfree(&evt_list); > > > + return; > > > + > > > +out_close_evt_dir: > > > + closedir(evt_dir); > > > +out_close_sys_dir: > > > + closedir(sys_dir); > > > + > > > + printf("FATAL: not enough memory to print %s\n", > > > + event_type_descriptors[PERF_TYPE_TRACEPOINT]); > > > + if (evt_list) > > > + goto out_free; > > > +} > > > + > > > +void print_sdt_events(const char *subsys_glob, const char *event_glob, > > > + bool name_only) > > > +{ > > > + struct probe_cache *pcache; > > > + struct probe_cache_entry *ent; > > > + struct strlist *bidlist, *sdtlist; > > > + struct strlist_config cfg = {.dont_dupstr = true}; > > > + struct str_node *nd, *nd2; > > > + char *buf, *path, *ptr = NULL; > > > + bool show_detail = false; > > > + int ret; > > > + > > > + sdtlist = strlist__new(NULL, &cfg); > > > + if (!sdtlist) { > > > + pr_debug("Failed to allocate new strlist for SDT\n"); > > > + return; > > > + } > > > + bidlist = build_id_cache__list_all(true); > > > + if (!bidlist) { > > > + pr_debug("Failed to get buildids: %d\n", errno); > > > + return; > > > + } > > > + strlist__for_each_entry(nd, bidlist) { > > > + pcache = probe_cache__new(nd->s, NULL); > > > + if (!pcache) > > > + continue; > > > + list_for_each_entry(ent, &pcache->entries, node) { > > > + if (!ent->sdt) > > > + continue; > > > + if (subsys_glob && > > > + !strglobmatch(ent->pev.group, subsys_glob)) > > > + continue; > > > + if (event_glob && > > > + !strglobmatch(ent->pev.event, event_glob)) > > > + continue; > > > + ret = asprintf(&buf, "%s:%s@%s", ent->pev.group, > > > + ent->pev.event, nd->s); > > > + if (ret > 0) > > > + strlist__add(sdtlist, buf); > > > + } > > > + probe_cache__delete(pcache); > > > + } > > > + strlist__delete(bidlist); > > > + > > > + strlist__for_each_entry(nd, sdtlist) { > > > + buf = strchr(nd->s, '@'); > > > + if (buf) > > > + *(buf++) = '\0'; > > > + if (name_only) { > > > + printf("%s ", nd->s); > > > + continue; > > > + } > > > + nd2 = strlist__next(nd); > > > + if (nd2) { > > > + ptr = strchr(nd2->s, '@'); > > > + if (ptr) > > > + *ptr = '\0'; > > > + if (strcmp(nd->s, nd2->s) == 0) > > > + show_detail = true; > > > + } > > > + if (show_detail) { > > > + path = build_id_cache__origname(buf); > > > + ret = asprintf(&buf, "%s@%s(%.12s)", nd->s, path, > > buf); > > > + if (ret > 0) { > > > + printf(" %-50s [%s]\n", buf, "SDT event"); > > > + free(buf); > > > + } > > > + free(path); > > > + } else > > > + printf(" %-50s [%s]\n", nd->s, "SDT event"); > > > + if (nd2) { > > > + if (strcmp(nd->s, nd2->s) != 0) > > > + show_detail = false; > > > + if (ptr) > > > + *ptr = '@'; > > > + } > > > + } > > > + strlist__delete(sdtlist); > > > +} > > > + > > > +static bool is_event_supported(u8 type, unsigned int config) > > > +{ > > > + bool ret = true; > > > + int open_return; > > > + struct evsel *evsel; > > > + struct perf_event_attr attr = { > > > + .type = type, > > > + .config = config, > > > + .disabled = 1, > > > + }; > > > + struct perf_thread_map *tmap = thread_map__new_by_tid(0); > > > + > > > + if (tmap == NULL) > > > + return false; > > > + > > > + evsel = evsel__new(&attr); > > > + if (evsel) { > > > + open_return = evsel__open(evsel, NULL, tmap); > > > + ret = open_return >= 0; > > > + > > > + if (open_return == -EACCES) { > > > + /* > > > + * This happens if the paranoid value > > > + * /proc/sys/kernel/perf_event_paranoid is set to 2 > > > + * Re-run with exclude_kernel set; we don't do that > > > + * by default as some ARM machines do not support > > it. > > > + * > > > + */ > > > + evsel->core.attr.exclude_kernel = 1; > > > + ret = evsel__open(evsel, NULL, tmap) >= 0; > > > + } > > > + evsel__delete(evsel); > > > + } > > > + > > > + perf_thread_map__put(tmap); > > > + return ret; > > > +} > > > + > > > +int print_hwcache_events(const char *event_glob, bool name_only) > > > +{ > > > + unsigned int type, op, i, evt_i = 0, evt_num = 0; > > > + char name[64]; > > > + char **evt_list = NULL; > > > + bool evt_num_known = false; > > > + > > > +restart: > > > + if (evt_num_known) { > > > + evt_list = zalloc(sizeof(char *) * evt_num); > > > + if (!evt_list) > > > + goto out_enomem; > > > + } > > > + > > > + for (type = 0; type < PERF_COUNT_HW_CACHE_MAX; type++) { > > > + for (op = 0; op < PERF_COUNT_HW_CACHE_OP_MAX; op++) { > > > + /* skip invalid cache type */ > > > + if (!evsel__is_cache_op_valid(type, op)) > > > + continue; > > > + > > > + for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; > > i++) { > > > + __evsel__hw_cache_type_op_res_name(type, > > op, i, name, sizeof(name)); > > > + if (event_glob != NULL && > > !strglobmatch(name, event_glob)) > > > + continue; > > > + > > > + if (!is_event_supported(PERF_TYPE_HW_CACHE, > > > + type | (op << 8) | > > (i << 16))) > > > + continue; > > > + > > > + if (!evt_num_known) { > > > + evt_num++; > > > + continue; > > > + } > > > + > > > + evt_list[evt_i] = strdup(name); > > > + if (evt_list[evt_i] == NULL) > > > + goto out_enomem; > > > + evt_i++; > > > + } > > > + } > > > + } > > > + > > > + if (!evt_num_known) { > > > + evt_num_known = true; > > > + goto restart; > > > + } > > > + qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > > + evt_i = 0; > > > + while (evt_i < evt_num) { > > > + if (name_only) { > > > + printf("%s ", evt_list[evt_i++]); > > > + continue; > > > + } > > > + printf(" %-50s [%s]\n", evt_list[evt_i++], > > > + > > event_type_descriptors[PERF_TYPE_HW_CACHE]); > > > + } > > > + if (evt_num && pager_in_use()) > > > + printf("\n"); > > > + > > > +out_free: > > > + evt_num = evt_i; > > > + for (evt_i = 0; evt_i < evt_num; evt_i++) > > > + zfree(&evt_list[evt_i]); > > > + zfree(&evt_list); > > > + return evt_num; > > > + > > > +out_enomem: > > > + printf("FATAL: not enough memory to print %s\n", > > event_type_descriptors[PERF_TYPE_HW_CACHE]); > > > + if (evt_list) > > > + goto out_free; > > > + return evt_num; > > > +} > > > + > > > +static void print_tool_event(const char *name, const char *event_glob, > > > + bool name_only) > > > +{ > > > + if (event_glob && !strglobmatch(name, event_glob)) > > > + return; > > > + if (name_only) > > > + printf("%s ", name); > > > + else > > > + printf(" %-50s [%s]\n", name, "Tool event"); > > > + > > > +} > > > + > > > +void print_tool_events(const char *event_glob, bool name_only) > > > +{ > > > + print_tool_event("duration_time", event_glob, name_only); > > > + if (pager_in_use()) > > > + printf("\n"); > > > +} > > > + > > > +void print_symbol_events(const char *event_glob, unsigned int type, > > > + struct event_symbol *syms, unsigned int max, > > > + bool name_only) > > > +{ > > > + unsigned int i, evt_i = 0, evt_num = 0; > > > + char name[MAX_NAME_LEN]; > > > + char **evt_list = NULL; > > > + bool evt_num_known = false; > > > + > > > +restart: > > > + if (evt_num_known) { > > > + evt_list = zalloc(sizeof(char *) * evt_num); > > > + if (!evt_list) > > > + goto out_enomem; > > > + syms -= max; > > > + } > > > + > > > + for (i = 0; i < max; i++, syms++) { > > > + > > > + if (event_glob != NULL && syms->symbol != NULL && > > > + !(strglobmatch(syms->symbol, event_glob) || > > > + (syms->alias && strglobmatch(syms->alias, > > event_glob)))) > > > + continue; > > > + > > > + if (!is_event_supported(type, i)) > > > + continue; > > > + > > > + if (!evt_num_known) { > > > + evt_num++; > > > + continue; > > > + } > > > + > > > + if (!name_only && strlen(syms->alias)) > > > + snprintf(name, MAX_NAME_LEN, "%s OR %s", > > syms->symbol, syms->alias); > > > + else > > > + strlcpy(name, syms->symbol, MAX_NAME_LEN); > > > + > > > + evt_list[evt_i] = strdup(name); > > > + if (evt_list[evt_i] == NULL) > > > + goto out_enomem; > > > + evt_i++; > > > + } > > > + > > > + if (!evt_num_known) { > > > + evt_num_known = true; > > > + goto restart; > > > + } > > > + qsort(evt_list, evt_num, sizeof(char *), cmp_string); > > > + evt_i = 0; > > > + while (evt_i < evt_num) { > > > + if (name_only) { > > > + printf("%s ", evt_list[evt_i++]); > > > + continue; > > > + } > > > + printf(" %-50s [%s]\n", evt_list[evt_i++], > > event_type_descriptors[type]); > > > + } > > > + if (evt_num && pager_in_use()) > > > + printf("\n"); > > > + > > > +out_free: > > > + evt_num = evt_i; > > > + for (evt_i = 0; evt_i < evt_num; evt_i++) > > > + zfree(&evt_list[evt_i]); > > > + zfree(&evt_list); > > > + return; > > > + > > > +out_enomem: > > > + printf("FATAL: not enough memory to print %s\n", > > event_type_descriptors[type]); > > > + if (evt_list) > > > + goto out_free; > > > +} > > > + > > > +/* > > > + * Print the help text for the event symbols: > > > + */ > > > +void print_events(const char *event_glob, bool name_only, bool > > quiet_flag, > > > + bool long_desc, bool details_flag, bool deprecated) > > > +{ > > > + print_symbol_events(event_glob, PERF_TYPE_HARDWARE, > > > + event_symbols_hw, PERF_COUNT_HW_MAX, > > name_only); > > > + > > > + print_symbol_events(event_glob, PERF_TYPE_SOFTWARE, > > > + event_symbols_sw, PERF_COUNT_SW_MAX, > > name_only); > > > + print_tool_events(event_glob, name_only); > > > + > > > + print_hwcache_events(event_glob, name_only); > > > + > > > + print_pmu_events(event_glob, name_only, quiet_flag, long_desc, > > > + details_flag, deprecated); > > > + > > > + if (event_glob != NULL) > > > + return; > > > + > > > + if (!name_only) { > > > + printf(" %-50s [%s]\n", > > > + "rNNN", > > > + event_type_descriptors[PERF_TYPE_RAW]); > > > + printf(" %-50s [%s]\n", > > > + "cpu/t1=v1[,t2=v2,t3 ...]/modifier", > > > + event_type_descriptors[PERF_TYPE_RAW]); > > > + if (pager_in_use()) > > > + printf(" (see 'man perf-list' on how to encode > > it)\n\n"); > > > + > > > + printf(" %-50s [%s]\n", > > > + "mem:<addr>[/len][:access]", > > > + event_type_descriptors[PERF_TYPE_BREAKPOINT]); > > > + if (pager_in_use()) > > > + printf("\n"); > > > + } > > > + > > > + print_tracepoint_events(NULL, NULL, name_only); > > > + > > > + print_sdt_events(NULL, NULL, name_only); > > > + > > > + metricgroup__print(true, true, NULL, name_only, details_flag); > > > + > > > + print_libpfm_events(name_only, long_desc); > > > +} > > > diff --git a/tools/perf/util/print-events.h > > b/tools/perf/util/print-events.h > > > new file mode 100644 > > > index 000000000000..cf64e8129c1b > > > --- /dev/null > > > +++ b/tools/perf/util/print-events.h > > > @@ -0,0 +1,21 @@ > > > +/* SPDX-License-Identifier: GPL-2.0 */ > > > +#ifndef __PERF_PRINT_EVENTS_H > > > +#define __PERF_PRINT_EVENTS_H > > > + > > > +#include <stdbool.h> > > > + > > > +struct event_symbol; > > > + > > > +void print_events(const char *event_glob, bool name_only, bool quiet, > > > + bool long_desc, bool details_flag, bool deprecated); > > > +int print_hwcache_events(const char *event_glob, bool name_only); > > > +void print_sdt_events(const char *subsys_glob, const char *event_glob, > > > + bool name_only); > > > +void print_symbol_events(const char *event_glob, unsigned int type, > > > + struct event_symbol *syms, unsigned int max, > > > + bool name_only); > > > +void print_tool_events(const char *event_glob, bool name_only); > > > +void print_tracepoint_events(const char *subsys_glob, const char > > *event_glob, > > > + bool name_only); > > > + > > > +#endif /* __PERF_PRINT_EVENTS_H */ > > > diff --git a/tools/perf/util/trace-event-info.c > > b/tools/perf/util/trace-event-info.c > > > index a65f65d0857e..fbc6d14aabbb 100644 > > > --- a/tools/perf/util/trace-event-info.c > > > +++ b/tools/perf/util/trace-event-info.c > > > @@ -19,16 +19,24 @@ > > > #include <linux/kernel.h> > > > #include <linux/zalloc.h> > > > #include <internal/lib.h> // page_size > > > +#include <sys/param.h> > > > > > > #include "trace-event.h" > > > +#include "tracepoint.h" > > > #include <api/fs/tracing_path.h> > > > #include "evsel.h" > > > #include "debug.h" > > > > > > #define VERSION "0.6" > > > +#define MAX_EVENT_LENGTH 512 > > > > > > static int output_fd; > > > > > > +struct tracepoint_path { > > > + char *system; > > > + char *name; > > > + struct tracepoint_path *next; > > > +}; > > > > > > int bigendian(void) > > > { > > > @@ -400,6 +408,92 @@ put_tracepoints_path(struct tracepoint_path *tps) > > > } > > > } > > > > > > +static struct tracepoint_path *tracepoint_id_to_path(u64 config) > > > +{ > > > + struct tracepoint_path *path = NULL; > > > + DIR *sys_dir, *evt_dir; > > > + struct dirent *sys_dirent, *evt_dirent; > > > + char id_buf[24]; > > > + int fd; > > > + u64 id; > > > + char evt_path[MAXPATHLEN]; > > > + char *dir_path; > > > + > > > + sys_dir = tracing_events__opendir(); > > > + if (!sys_dir) > > > + return NULL; > > > + > > > + for_each_subsystem(sys_dir, sys_dirent) { > > > + dir_path = get_events_file(sys_dirent->d_name); > > > + if (!dir_path) > > > + continue; > > > + evt_dir = opendir(dir_path); > > > + if (!evt_dir) > > > + goto next; > > > + > > > + for_each_event(dir_path, evt_dir, evt_dirent) { > > > + > > > + scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", > > dir_path, > > > + evt_dirent->d_name); > > > + fd = open(evt_path, O_RDONLY); > > > + if (fd < 0) > > > + continue; > > > + if (read(fd, id_buf, sizeof(id_buf)) < 0) { > > > + close(fd); > > > + continue; > > > + } > > > + close(fd); > > > + id = atoll(id_buf); > > > + if (id == config) { > > > + put_events_file(dir_path); > > > + closedir(evt_dir); > > > + closedir(sys_dir); > > > + path = zalloc(sizeof(*path)); > > > + if (!path) > > > + return NULL; > > > + if (asprintf(&path->system, "%.*s", > > MAX_EVENT_LENGTH, sys_dirent->d_name) < 0) { > > > + free(path); > > > + return NULL; > > > + } > > > + if (asprintf(&path->name, "%.*s", > > MAX_EVENT_LENGTH, evt_dirent->d_name) < 0) { > > > + zfree(&path->system); > > > + free(path); > > > + return NULL; > > > + } > > > + return path; > > > + } > > > + } > > > + closedir(evt_dir); > > > +next: > > > + put_events_file(dir_path); > > > + } > > > + > > > + closedir(sys_dir); > > > + return NULL; > > > +} > > > + > > > +static struct tracepoint_path *tracepoint_name_to_path(const char *name) > > > +{ > > > + struct tracepoint_path *path = zalloc(sizeof(*path)); > > > + char *str = strchr(name, ':'); > > > + > > > + if (path == NULL || str == NULL) { > > > + free(path); > > > + return NULL; > > > + } > > > + > > > + path->system = strndup(name, str - name); > > > + path->name = strdup(str+1); > > > + > > > + if (path->system == NULL || path->name == NULL) { > > > + zfree(&path->system); > > > + zfree(&path->name); > > > + zfree(&path); > > > + } > > > + > > > + return path; > > > +} > > > + > > > static struct tracepoint_path * > > > get_tracepoints_path(struct list_head *pattrs) > > > { > > > diff --git a/tools/perf/util/tracepoint.c b/tools/perf/util/tracepoint.c > > > new file mode 100644 > > > index 000000000000..89ef56c43311 > > > --- /dev/null > > > +++ b/tools/perf/util/tracepoint.c > > > @@ -0,0 +1,63 @@ > > > +// SPDX-License-Identifier: GPL-2.0 > > > +#include "tracepoint.h" > > > + > > > +#include <errno.h> > > > +#include <fcntl.h> > > > +#include <stdio.h> > > > +#include <sys/param.h> > > > +#include <unistd.h> > > > + > > > +#include <api/fs/tracing_path.h> > > > + > > > +int tp_event_has_id(const char *dir_path, struct dirent *evt_dir) > > > +{ > > > + char evt_path[MAXPATHLEN]; > > > + int fd; > > > + > > > + snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, > > evt_dir->d_name); > > > + fd = open(evt_path, O_RDONLY); > > > + if (fd < 0) > > > + return -EINVAL; > > > + close(fd); > > > + > > > + return 0; > > > +} > > > + > > > +/* > > > + * Check whether event is in <debugfs_mount_point>/tracing/events > > > + */ > > > +int is_valid_tracepoint(const char *event_string) > > > +{ > > > + DIR *sys_dir, *evt_dir; > > > + struct dirent *sys_dirent, *evt_dirent; > > > + char evt_path[MAXPATHLEN]; > > > + char *dir_path; > > > + > > > + sys_dir = tracing_events__opendir(); > > > + if (!sys_dir) > > > + return 0; > > > + > > > + for_each_subsystem(sys_dir, sys_dirent) { > > > + dir_path = get_events_file(sys_dirent->d_name); > > > + if (!dir_path) > > > + continue; > > > + evt_dir = opendir(dir_path); > > > + if (!evt_dir) > > > + goto next; > > > + > > > + for_each_event(dir_path, evt_dir, evt_dirent) { > > > + snprintf(evt_path, MAXPATHLEN, "%s:%s", > > > + sys_dirent->d_name, evt_dirent->d_name); > > > + if (!strcmp(evt_path, event_string)) { > > > + closedir(evt_dir); > > > + closedir(sys_dir); > > > + return 1; > > > + } > > > + } > > > + closedir(evt_dir); > > > +next: > > > + put_events_file(dir_path); > > > + } > > > + closedir(sys_dir); > > > + return 0; > > > +} > > > diff --git a/tools/perf/util/tracepoint.h b/tools/perf/util/tracepoint.h > > > new file mode 100644 > > > index 000000000000..c4a110fe87d7 > > > --- /dev/null > > > +++ b/tools/perf/util/tracepoint.h > > > @@ -0,0 +1,25 @@ > > > +/* SPDX-License-Identifier: GPL-2.0 */ > > > +#ifndef __PERF_TRACEPOINT_H > > > +#define __PERF_TRACEPOINT_H > > > + > > > +#include <dirent.h> > > > +#include <string.h> > > > + > > > +int tp_event_has_id(const char *dir_path, struct dirent *evt_dir); > > > + > > > +#define for_each_event(dir_path, evt_dir, evt_dirent) \ > > > + while ((evt_dirent = readdir(evt_dir)) != NULL) \ > > > + if (evt_dirent->d_type == DT_DIR && \ > > > + (strcmp(evt_dirent->d_name, ".")) && \ > > > + (strcmp(evt_dirent->d_name, "..")) && \ > > > + (!tp_event_has_id(dir_path, evt_dirent))) > > > + > > > +#define for_each_subsystem(sys_dir, sys_dirent) \ > > > + while ((sys_dirent = readdir(sys_dir)) != NULL) \ > > > + if (sys_dirent->d_type == DT_DIR && \ > > > + (strcmp(sys_dirent->d_name, ".")) && \ > > > + (strcmp(sys_dirent->d_name, ".."))) > > > + > > > +int is_valid_tracepoint(const char *event_string); > > > + > > > +#endif /* __PERF_TRACEPOINT_H */ > > > -- > > > 2.30.0.365.g02bc693789-goog > > > > > > > -- > > > > - Arnaldo > > -- - Arnaldo ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] perf parse-events: Break out tracepoint and printing. 2021-02-03 20:50 ` Arnaldo Carvalho de Melo @ 2021-02-04 0:58 ` Arnaldo Carvalho de Melo 2021-02-04 1:21 ` Ian Rogers 0 siblings, 1 reply; 8+ messages in thread From: Arnaldo Carvalho de Melo @ 2021-02-04 0:58 UTC (permalink / raw) To: Ian Rogers Cc: Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim, LKML, Stephane Eranian Em Wed, Feb 03, 2021 at 05:50:24PM -0300, Arnaldo Carvalho de Melo escreveu: > Em Wed, Feb 03, 2021 at 10:38:41AM -0800, Ian Rogers escreveu: > > On Wed, Feb 3, 2021 at 8:21 AM Arnaldo Carvalho de Melo <acme@kernel.org> > > wrote: > > > > > Em Tue, Feb 02, 2021 at 09:26:59PM -0800, Ian Rogers escreveu: > > > > Move print_*_events functions out of parse-events.c into a new > > > > print-events.c. Move tracepoint code into tracepoint.c or > > > > trace-event-info.c (sole user). This reduces the dependencies of > > > > parse-events.c and makes it more amenable to being a library in the > > > > future. > > > > Remove some unnecessary definitions from parse-events.h. Fix a > > > > checkpatch.pl warning on using unsigned rather than unsigned int. > > > > > > Thanks, applied. > > > > > > > Wow, cool :-) I wasn't sure about the macros in the headers. Are you > > staging these patches before pushing to your perf/core or using > > tmp.perf/core ? I know you mentioned a different approach. When I look at: > > > > https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/ > > > > I don't see anything newer than 9 days. > > Right, I'm collecting some more patches, will do build tests and push, > till then, lemme push tmp.perf/core with what I have. Strange, some intermediary versions of Alpine Linux are complaining, I'll continue tomorrow morning :-\ [perfbuilder@five ~]$ time dm Wed Feb 3 09:32:47 PM -03 2021 # export PERF_TARBALL=http://192.168.86.5/perf/perf-5.11.0-rc6.tar.xz # dm 1 72.90 alpine:3.4 : Ok gcc (Alpine 5.3.0) 5.3.0, clang version 3.8.0 (tags/RELEASE_380/final) 2 74.62 alpine:3.5 : Ok gcc (Alpine 6.2.1) 6.2.1 20160822, clang version 3.8.1 (tags/RELEASE_381/final) 3 76.69 alpine:3.6 : Ok gcc (Alpine 6.3.0) 6.3.0, clang version 4.0.0 (tags/RELEASE_400/final) 4 84.43 alpine:3.7 : Ok gcc (Alpine 6.4.0) 6.4.0, Alpine clang version 5.0.0 (tags/RELEASE_500/final) (based on LLVM 5.0.0) 5 84.17 alpine:3.8 : Ok gcc (Alpine 6.4.0) 6.4.0, Alpine clang version 5.0.1 (tags/RELEASE_501/final) (based on LLVM 5.0.1) 6 16.71 alpine:3.9 : FAIL gcc (Alpine 8.3.0) 8.3.0, Alpine clang version 5.0.1 (tags/RELEASE_502/final) (based on LLVM 5.0.1) from util/print-events.c:10: /usr/include/linux/swab.h:161:8: error: unknown type name '__always_inline' static __always_inline __u16 __swab16p(const __u16 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/swab.h:161:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab16p' static __always_inline __u16 __swab16p(const __u16 *p) ^~~~~~~~~ /usr/include/linux/swab.h:174:8: error: unknown type name '__always_inline' static __always_inline __u32 __swab32p(const __u32 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/swab.h:174:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab32p' static __always_inline __u32 __swab32p(const __u32 *p) ^~~~~~~~~ /usr/include/linux/swab.h:187:8: error: unknown type name '__always_inline' static __always_inline __u64 __swab64p(const __u64 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/swab.h:187:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab64p' static __always_inline __u64 __swab64p(const __u64 *p) ^~~~~~~~~ /usr/include/linux/swab.h:242:23: error: expected ';' before 'void' static __always_inline void __swab32s(__u32 *p) ^~~~~ ; /usr/include/linux/swab.h:255:23: error: expected ';' before 'void' static __always_inline void __swab64s(__u64 *p) ^~~~~ ; In file included from /usr/include/asm/byteorder.h:5, from /git/linux/tools/include/uapi/linux/perf_event.h:20, from util/print-events.c:10: /usr/include/linux/byteorder/little_endian.h:44:8: error: unknown type name '__always_inline' static __always_inline __le64 __cpu_to_le64p(const __u64 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:44:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le64p' static __always_inline __le64 __cpu_to_le64p(const __u64 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:48:8: error: unknown type name '__always_inline' static __always_inline __u64 __le64_to_cpup(const __le64 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:48:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le64_to_cpup' static __always_inline __u64 __le64_to_cpup(const __le64 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:52:8: error: unknown type name '__always_inline' static __always_inline __le32 __cpu_to_le32p(const __u32 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:52:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le32p' static __always_inline __le32 __cpu_to_le32p(const __u32 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:56:8: error: unknown type name '__always_inline' static __always_inline __u32 __le32_to_cpup(const __le32 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:56:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le32_to_cpup' static __always_inline __u32 __le32_to_cpup(const __le32 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:60:8: error: unknown type name '__always_inline' static __always_inline __le16 __cpu_to_le16p(const __u16 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:60:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le16p' static __always_inline __le16 __cpu_to_le16p(const __u16 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:64:8: error: unknown type name '__always_inline' static __always_inline __u16 __le16_to_cpup(const __le16 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:64:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le16_to_cpup' static __always_inline __u16 __le16_to_cpup(const __le16 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:68:8: error: unknown type name '__always_inline' static __always_inline __be64 __cpu_to_be64p(const __u64 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:68:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be64p' static __always_inline __be64 __cpu_to_be64p(const __u64 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:72:8: error: unknown type name '__always_inline' static __always_inline __u64 __be64_to_cpup(const __be64 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:72:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be64_to_cpup' static __always_inline __u64 __be64_to_cpup(const __be64 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:76:8: error: unknown type name '__always_inline' static __always_inline __be32 __cpu_to_be32p(const __u32 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:76:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be32p' static __always_inline __be32 __cpu_to_be32p(const __u32 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:80:8: error: unknown type name '__always_inline' static __always_inline __u32 __be32_to_cpup(const __be32 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:80:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be32_to_cpup' static __always_inline __u32 __be32_to_cpup(const __be32 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:84:8: error: unknown type name '__always_inline' static __always_inline __be16 __cpu_to_be16p(const __u16 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:84:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be16p' static __always_inline __be16 __cpu_to_be16p(const __u16 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:88:8: error: unknown type name '__always_inline' static __always_inline __u16 __be16_to_cpup(const __be16 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:88:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be16_to_cpup' static __always_inline __u16 __be16_to_cpup(const __be16 *p) ^~~~~~~~~~~~~~ make[3]: *** [/git/linux/tools/build/Makefile.build:139: util] Error 2 7 16.31 alpine:3.10 : FAIL gcc (Alpine 8.3.0) 8.3.0, Alpine clang version 8.0.0 (tags/RELEASE_800/final) (based on LLVM 8.0.0) from util/print-events.c:10: /usr/include/linux/swab.h:161:8: error: unknown type name '__always_inline' static __always_inline __u16 __swab16p(const __u16 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/swab.h:161:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab16p' static __always_inline __u16 __swab16p(const __u16 *p) ^~~~~~~~~ /usr/include/linux/swab.h:174:8: error: unknown type name '__always_inline' static __always_inline __u32 __swab32p(const __u32 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/swab.h:174:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab32p' static __always_inline __u32 __swab32p(const __u32 *p) ^~~~~~~~~ /usr/include/linux/swab.h:187:8: error: unknown type name '__always_inline' static __always_inline __u64 __swab64p(const __u64 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/swab.h:187:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab64p' static __always_inline __u64 __swab64p(const __u64 *p) ^~~~~~~~~ /usr/include/linux/swab.h:242:23: error: expected ';' before 'void' static __always_inline void __swab32s(__u32 *p) ^~~~~ ; /usr/include/linux/swab.h:255:23: error: expected ';' before 'void' static __always_inline void __swab64s(__u64 *p) ^~~~~ ; In file included from /usr/include/asm/byteorder.h:5, from /git/linux/tools/include/uapi/linux/perf_event.h:20, from util/print-events.c:10: /usr/include/linux/byteorder/little_endian.h:44:8: error: unknown type name '__always_inline' static __always_inline __le64 __cpu_to_le64p(const __u64 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:44:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le64p' static __always_inline __le64 __cpu_to_le64p(const __u64 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:48:8: error: unknown type name '__always_inline' static __always_inline __u64 __le64_to_cpup(const __le64 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:48:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le64_to_cpup' static __always_inline __u64 __le64_to_cpup(const __le64 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:52:8: error: unknown type name '__always_inline' static __always_inline __le32 __cpu_to_le32p(const __u32 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:52:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le32p' static __always_inline __le32 __cpu_to_le32p(const __u32 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:56:8: error: unknown type name '__always_inline' static __always_inline __u32 __le32_to_cpup(const __le32 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:56:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le32_to_cpup' static __always_inline __u32 __le32_to_cpup(const __le32 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:60:8: error: unknown type name '__always_inline' static __always_inline __le16 __cpu_to_le16p(const __u16 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:60:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le16p' static __always_inline __le16 __cpu_to_le16p(const __u16 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:64:8: error: unknown type name '__always_inline' static __always_inline __u16 __le16_to_cpup(const __le16 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:64:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le16_to_cpup' static __always_inline __u16 __le16_to_cpup(const __le16 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:68:8: error: unknown type name '__always_inline' static __always_inline __be64 __cpu_to_be64p(const __u64 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:68:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be64p' static __always_inline __be64 __cpu_to_be64p(const __u64 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:72:8: error: unknown type name '__always_inline' static __always_inline __u64 __be64_to_cpup(const __be64 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:72:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be64_to_cpup' static __always_inline __u64 __be64_to_cpup(const __be64 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:76:8: error: unknown type name '__always_inline' static __always_inline __be32 __cpu_to_be32p(const __u32 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:76:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be32p' static __always_inline __be32 __cpu_to_be32p(const __u32 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:80:8: error: unknown type name '__always_inline' static __always_inline __u32 __be32_to_cpup(const __be32 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:80:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be32_to_cpup' static __always_inline __u32 __be32_to_cpup(const __be32 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:84:8: error: unknown type name '__always_inline' static __always_inline __be16 __cpu_to_be16p(const __u16 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:84:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be16p' static __always_inline __be16 __cpu_to_be16p(const __u16 *p) ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:88:8: error: unknown type name '__always_inline' static __always_inline __u16 __be16_to_cpup(const __be16 *p) ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:88:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be16_to_cpup' static __always_inline __u16 __be16_to_cpup(const __be16 *p) ^~~~~~~~~~~~~~ make[3]: *** [/git/linux/tools/build/Makefile.build:139: util] Error 2 8 18.59 alpine:3.11 : FAIL gcc (Alpine 9.3.0) 9.3.0, Alpine clang version 9.0.0 (https://git.alpinelinux.org/aports f7f0d2c2b8bcd6a5843401a9a702029556492689) (based on LLVM 9.0.0) from util/print-events.c:10: /usr/include/linux/swab.h:161:8: error: unknown type name '__always_inline' 161 | static __always_inline __u16 __swab16p(const __u16 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/swab.h:161:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab16p' 161 | static __always_inline __u16 __swab16p(const __u16 *p) | ^~~~~~~~~ /usr/include/linux/swab.h:174:8: error: unknown type name '__always_inline' 174 | static __always_inline __u32 __swab32p(const __u32 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/swab.h:174:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab32p' 174 | static __always_inline __u32 __swab32p(const __u32 *p) | ^~~~~~~~~ /usr/include/linux/swab.h:187:8: error: unknown type name '__always_inline' 187 | static __always_inline __u64 __swab64p(const __u64 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/swab.h:187:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab64p' 187 | static __always_inline __u64 __swab64p(const __u64 *p) | ^~~~~~~~~ /usr/include/linux/swab.h:242:23: error: expected ';' before 'void' 242 | static __always_inline void __swab32s(__u32 *p) | ^~~~~ | ; /usr/include/linux/swab.h:255:23: error: expected ';' before 'void' 255 | static __always_inline void __swab64s(__u64 *p) | ^~~~~ | ; In file included from /usr/include/asm/byteorder.h:5, from /git/linux/tools/include/uapi/linux/perf_event.h:20, from util/print-events.c:10: /usr/include/linux/byteorder/little_endian.h:44:8: error: unknown type name '__always_inline' 44 | static __always_inline __le64 __cpu_to_le64p(const __u64 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:44:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le64p' 44 | static __always_inline __le64 __cpu_to_le64p(const __u64 *p) | ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:48:8: error: unknown type name '__always_inline' 48 | static __always_inline __u64 __le64_to_cpup(const __le64 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:48:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le64_to_cpup' 48 | static __always_inline __u64 __le64_to_cpup(const __le64 *p) | ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:52:8: error: unknown type name '__always_inline' 52 | static __always_inline __le32 __cpu_to_le32p(const __u32 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:52:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le32p' 52 | static __always_inline __le32 __cpu_to_le32p(const __u32 *p) | ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:56:8: error: unknown type name '__always_inline' 56 | static __always_inline __u32 __le32_to_cpup(const __le32 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:56:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le32_to_cpup' 56 | static __always_inline __u32 __le32_to_cpup(const __le32 *p) | ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:60:8: error: unknown type name '__always_inline' 60 | static __always_inline __le16 __cpu_to_le16p(const __u16 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:60:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le16p' 60 | static __always_inline __le16 __cpu_to_le16p(const __u16 *p) | ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:64:8: error: unknown type name '__always_inline' 64 | static __always_inline __u16 __le16_to_cpup(const __le16 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:64:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le16_to_cpup' 64 | static __always_inline __u16 __le16_to_cpup(const __le16 *p) | ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:68:8: error: unknown type name '__always_inline' 68 | static __always_inline __be64 __cpu_to_be64p(const __u64 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:68:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be64p' 68 | static __always_inline __be64 __cpu_to_be64p(const __u64 *p) | ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:72:8: error: unknown type name '__always_inline' 72 | static __always_inline __u64 __be64_to_cpup(const __be64 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:72:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be64_to_cpup' 72 | static __always_inline __u64 __be64_to_cpup(const __be64 *p) | ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:76:8: error: unknown type name '__always_inline' 76 | static __always_inline __be32 __cpu_to_be32p(const __u32 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:76:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be32p' 76 | static __always_inline __be32 __cpu_to_be32p(const __u32 *p) | ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:80:8: error: unknown type name '__always_inline' 80 | static __always_inline __u32 __be32_to_cpup(const __be32 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:80:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be32_to_cpup' 80 | static __always_inline __u32 __be32_to_cpup(const __be32 *p) | ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:84:8: error: unknown type name '__always_inline' 84 | static __always_inline __be16 __cpu_to_be16p(const __u16 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:84:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be16p' 84 | static __always_inline __be16 __cpu_to_be16p(const __u16 *p) | ^~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:88:8: error: unknown type name '__always_inline' 88 | static __always_inline __u16 __be16_to_cpup(const __be16 *p) | ^~~~~~~~~~~~~~~ /usr/include/linux/byteorder/little_endian.h:88:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be16_to_cpup' 88 | static __always_inline __u16 __be16_to_cpup(const __be16 *p) | ^~~~~~~~~~~~~~ make[3]: *** [/git/linux/tools/build/Makefile.build:139: util] Error 2 9 117.31 alpine:3.12 : Ok gcc (Alpine 9.3.0) 9.3.0, Alpine clang version 10.0.0 (https://gitlab.alpinelinux.org/alpine/aports.git 7445adce501f8473efdb93b17b5eaf2f1445ed4c) 10 124.70 alpine:edge : Ok gcc (Alpine 10.2.0) 10.2.0, Alpine clang version 10.0.1 11 72.02 alt:p8 : Ok x86_64-alt-linux-gcc (GCC) 5.3.1 20151207 (ALT p8 5.3.1-alt3.M80P.1), clang version 3.8.0 (tags/RELEASE_380/final) 12 87.30 alt:p9 : Ok x86_64-alt-linux-gcc (GCC) 8.4.1 20200305 (ALT p9 8.4.1-alt0.p9.1), clang version 10.0.0 13 87.33 alt:sisyphus : Ok x86_64-alt-linux-gcc (GCC) 10.2.1 20201125 (ALT Sisyphus 10.2.1-alt2), clang version 10.0.1 14 70.23 amazonlinux:1 : Ok gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2), clang version 3.6.2 (tags/RELEASE_362/final) 15 104.56 amazonlinux:2 : Ok gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-12), clang version 7.0.1 (Amazon Linux 2 7.0.1-1.amzn2.0.2) 16 23.52 android-ndk:r12b-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease) 17 21.96 android-ndk:r15c-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease) 18 27.58 centos:6 : Ok gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23) 19 33.35 centos:7 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44) 20 98.93 centos:8 : Ok gcc (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5), clang version 10.0.1 (Red Hat 10.0.1-1.module_el8.3.0+467+cb298d5b) 21 69.01 clearlinux:latest : Ok gcc (Clear Linux OS for Intel Architecture) 10.2.1 20201217 releases/gcc-10.2.0-643-g7cbb07d2fc, clang version 10.0.1 22 79.89 debian:8 : Ok gcc (Debian 4.9.2-10+deb8u2) 4.9.2, Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0) ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] perf parse-events: Break out tracepoint and printing. 2021-02-04 0:58 ` Arnaldo Carvalho de Melo @ 2021-02-04 1:21 ` Ian Rogers 2021-06-08 20:41 ` Ian Rogers 0 siblings, 1 reply; 8+ messages in thread From: Ian Rogers @ 2021-02-04 1:21 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim, LKML, Stephane Eranian On Wed, Feb 3, 2021 at 4:58 PM Arnaldo Carvalho de Melo <acme@kernel.org> wrote: > > Em Wed, Feb 03, 2021 at 05:50:24PM -0300, Arnaldo Carvalho de Melo escreveu: > > Em Wed, Feb 03, 2021 at 10:38:41AM -0800, Ian Rogers escreveu: > > > On Wed, Feb 3, 2021 at 8:21 AM Arnaldo Carvalho de Melo <acme@kernel.org> > > > wrote: > > > > > > > Em Tue, Feb 02, 2021 at 09:26:59PM -0800, Ian Rogers escreveu: > > > > > Move print_*_events functions out of parse-events.c into a new > > > > > print-events.c. Move tracepoint code into tracepoint.c or > > > > > trace-event-info.c (sole user). This reduces the dependencies of > > > > > parse-events.c and makes it more amenable to being a library in the > > > > > future. > > > > > Remove some unnecessary definitions from parse-events.h. Fix a > > > > > checkpatch.pl warning on using unsigned rather than unsigned int. > > > > > > > > Thanks, applied. > > > > > > > > > > Wow, cool :-) I wasn't sure about the macros in the headers. Are you > > > staging these patches before pushing to your perf/core or using > > > tmp.perf/core ? I know you mentioned a different approach. When I look at: > > > > > > https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/ > > > > > > I don't see anything newer than 9 days. > > > > Right, I'm collecting some more patches, will do build tests and push, > > till then, lemme push tmp.perf/core with what I have. > > Strange, some intermediary versions of Alpine Linux are complaining, I'll continue tomorrow morning :-\ > > [perfbuilder@five ~]$ time dm > Wed Feb 3 09:32:47 PM -03 2021 > # export PERF_TARBALL=http://192.168.86.5/perf/perf-5.11.0-rc6.tar.xz > # dm > 1 72.90 alpine:3.4 : Ok gcc (Alpine 5.3.0) 5.3.0, clang version 3.8.0 (tags/RELEASE_380/final) > 2 74.62 alpine:3.5 : Ok gcc (Alpine 6.2.1) 6.2.1 20160822, clang version 3.8.1 (tags/RELEASE_381/final) > 3 76.69 alpine:3.6 : Ok gcc (Alpine 6.3.0) 6.3.0, clang version 4.0.0 (tags/RELEASE_400/final) > 4 84.43 alpine:3.7 : Ok gcc (Alpine 6.4.0) 6.4.0, Alpine clang version 5.0.0 (tags/RELEASE_500/final) (based on LLVM 5.0.0) > 5 84.17 alpine:3.8 : Ok gcc (Alpine 6.4.0) 6.4.0, Alpine clang version 5.0.1 (tags/RELEASE_501/final) (based on LLVM 5.0.1) > 6 16.71 alpine:3.9 : FAIL gcc (Alpine 8.3.0) 8.3.0, Alpine clang version 5.0.1 (tags/RELEASE_502/final) (based on LLVM 5.0.1) > from util/print-events.c:10: > /usr/include/linux/swab.h:161:8: error: unknown type name '__always_inline' > static __always_inline __u16 __swab16p(const __u16 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/swab.h:161:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab16p' > static __always_inline __u16 __swab16p(const __u16 *p) > ^~~~~~~~~ > /usr/include/linux/swab.h:174:8: error: unknown type name '__always_inline' > static __always_inline __u32 __swab32p(const __u32 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/swab.h:174:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab32p' > static __always_inline __u32 __swab32p(const __u32 *p) > ^~~~~~~~~ > /usr/include/linux/swab.h:187:8: error: unknown type name '__always_inline' > static __always_inline __u64 __swab64p(const __u64 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/swab.h:187:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab64p' > static __always_inline __u64 __swab64p(const __u64 *p) > ^~~~~~~~~ > /usr/include/linux/swab.h:242:23: error: expected ';' before 'void' > static __always_inline void __swab32s(__u32 *p) > ^~~~~ > ; > /usr/include/linux/swab.h:255:23: error: expected ';' before 'void' > static __always_inline void __swab64s(__u64 *p) > ^~~~~ > ; > In file included from /usr/include/asm/byteorder.h:5, > from /git/linux/tools/include/uapi/linux/perf_event.h:20, > from util/print-events.c:10: > /usr/include/linux/byteorder/little_endian.h:44:8: error: unknown type name '__always_inline' > static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:44:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le64p' > static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:48:8: error: unknown type name '__always_inline' > static __always_inline __u64 __le64_to_cpup(const __le64 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:48:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le64_to_cpup' > static __always_inline __u64 __le64_to_cpup(const __le64 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:52:8: error: unknown type name '__always_inline' > static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:52:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le32p' > static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:56:8: error: unknown type name '__always_inline' > static __always_inline __u32 __le32_to_cpup(const __le32 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:56:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le32_to_cpup' > static __always_inline __u32 __le32_to_cpup(const __le32 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:60:8: error: unknown type name '__always_inline' > static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:60:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le16p' > static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:64:8: error: unknown type name '__always_inline' > static __always_inline __u16 __le16_to_cpup(const __le16 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:64:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le16_to_cpup' > static __always_inline __u16 __le16_to_cpup(const __le16 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:68:8: error: unknown type name '__always_inline' > static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:68:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be64p' > static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:72:8: error: unknown type name '__always_inline' > static __always_inline __u64 __be64_to_cpup(const __be64 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:72:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be64_to_cpup' > static __always_inline __u64 __be64_to_cpup(const __be64 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:76:8: error: unknown type name '__always_inline' > static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:76:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be32p' > static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:80:8: error: unknown type name '__always_inline' > static __always_inline __u32 __be32_to_cpup(const __be32 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:80:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be32_to_cpup' > static __always_inline __u32 __be32_to_cpup(const __be32 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:84:8: error: unknown type name '__always_inline' > static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:84:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be16p' > static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:88:8: error: unknown type name '__always_inline' > static __always_inline __u16 __be16_to_cpup(const __be16 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:88:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be16_to_cpup' > static __always_inline __u16 __be16_to_cpup(const __be16 *p) > ^~~~~~~~~~~~~~ > make[3]: *** [/git/linux/tools/build/Makefile.build:139: util] Error 2 > 7 16.31 alpine:3.10 : FAIL gcc (Alpine 8.3.0) 8.3.0, Alpine clang version 8.0.0 (tags/RELEASE_800/final) (based on LLVM 8.0.0) > from util/print-events.c:10: > /usr/include/linux/swab.h:161:8: error: unknown type name '__always_inline' > static __always_inline __u16 __swab16p(const __u16 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/swab.h:161:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab16p' > static __always_inline __u16 __swab16p(const __u16 *p) > ^~~~~~~~~ > /usr/include/linux/swab.h:174:8: error: unknown type name '__always_inline' > static __always_inline __u32 __swab32p(const __u32 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/swab.h:174:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab32p' > static __always_inline __u32 __swab32p(const __u32 *p) > ^~~~~~~~~ > /usr/include/linux/swab.h:187:8: error: unknown type name '__always_inline' > static __always_inline __u64 __swab64p(const __u64 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/swab.h:187:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab64p' > static __always_inline __u64 __swab64p(const __u64 *p) > ^~~~~~~~~ > /usr/include/linux/swab.h:242:23: error: expected ';' before 'void' > static __always_inline void __swab32s(__u32 *p) > ^~~~~ > ; > /usr/include/linux/swab.h:255:23: error: expected ';' before 'void' > static __always_inline void __swab64s(__u64 *p) > ^~~~~ > ; > In file included from /usr/include/asm/byteorder.h:5, > from /git/linux/tools/include/uapi/linux/perf_event.h:20, > from util/print-events.c:10: > /usr/include/linux/byteorder/little_endian.h:44:8: error: unknown type name '__always_inline' > static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:44:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le64p' > static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:48:8: error: unknown type name '__always_inline' > static __always_inline __u64 __le64_to_cpup(const __le64 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:48:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le64_to_cpup' > static __always_inline __u64 __le64_to_cpup(const __le64 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:52:8: error: unknown type name '__always_inline' > static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:52:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le32p' > static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:56:8: error: unknown type name '__always_inline' > static __always_inline __u32 __le32_to_cpup(const __le32 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:56:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le32_to_cpup' > static __always_inline __u32 __le32_to_cpup(const __le32 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:60:8: error: unknown type name '__always_inline' > static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:60:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le16p' > static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:64:8: error: unknown type name '__always_inline' > static __always_inline __u16 __le16_to_cpup(const __le16 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:64:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le16_to_cpup' > static __always_inline __u16 __le16_to_cpup(const __le16 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:68:8: error: unknown type name '__always_inline' > static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:68:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be64p' > static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:72:8: error: unknown type name '__always_inline' > static __always_inline __u64 __be64_to_cpup(const __be64 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:72:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be64_to_cpup' > static __always_inline __u64 __be64_to_cpup(const __be64 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:76:8: error: unknown type name '__always_inline' > static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:76:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be32p' > static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:80:8: error: unknown type name '__always_inline' > static __always_inline __u32 __be32_to_cpup(const __be32 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:80:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be32_to_cpup' > static __always_inline __u32 __be32_to_cpup(const __be32 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:84:8: error: unknown type name '__always_inline' > static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:84:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be16p' > static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:88:8: error: unknown type name '__always_inline' > static __always_inline __u16 __be16_to_cpup(const __be16 *p) > ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:88:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be16_to_cpup' > static __always_inline __u16 __be16_to_cpup(const __be16 *p) > ^~~~~~~~~~~~~~ > make[3]: *** [/git/linux/tools/build/Makefile.build:139: util] Error 2 > 8 18.59 alpine:3.11 : FAIL gcc (Alpine 9.3.0) 9.3.0, Alpine clang version 9.0.0 (https://git.alpinelinux.org/aports f7f0d2c2b8bcd6a5843401a9a702029556492689) (based on LLVM 9.0.0) > from util/print-events.c:10: > /usr/include/linux/swab.h:161:8: error: unknown type name '__always_inline' > 161 | static __always_inline __u16 __swab16p(const __u16 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/swab.h:161:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab16p' > 161 | static __always_inline __u16 __swab16p(const __u16 *p) > | ^~~~~~~~~ > /usr/include/linux/swab.h:174:8: error: unknown type name '__always_inline' > 174 | static __always_inline __u32 __swab32p(const __u32 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/swab.h:174:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab32p' > 174 | static __always_inline __u32 __swab32p(const __u32 *p) > | ^~~~~~~~~ > /usr/include/linux/swab.h:187:8: error: unknown type name '__always_inline' > 187 | static __always_inline __u64 __swab64p(const __u64 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/swab.h:187:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab64p' > 187 | static __always_inline __u64 __swab64p(const __u64 *p) > | ^~~~~~~~~ > /usr/include/linux/swab.h:242:23: error: expected ';' before 'void' > 242 | static __always_inline void __swab32s(__u32 *p) > | ^~~~~ > | ; > /usr/include/linux/swab.h:255:23: error: expected ';' before 'void' > 255 | static __always_inline void __swab64s(__u64 *p) > | ^~~~~ > | ; > In file included from /usr/include/asm/byteorder.h:5, > from /git/linux/tools/include/uapi/linux/perf_event.h:20, > from util/print-events.c:10: > /usr/include/linux/byteorder/little_endian.h:44:8: error: unknown type name '__always_inline' > 44 | static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:44:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le64p' > 44 | static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > | ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:48:8: error: unknown type name '__always_inline' > 48 | static __always_inline __u64 __le64_to_cpup(const __le64 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:48:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le64_to_cpup' > 48 | static __always_inline __u64 __le64_to_cpup(const __le64 *p) > | ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:52:8: error: unknown type name '__always_inline' > 52 | static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:52:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le32p' > 52 | static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > | ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:56:8: error: unknown type name '__always_inline' > 56 | static __always_inline __u32 __le32_to_cpup(const __le32 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:56:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le32_to_cpup' > 56 | static __always_inline __u32 __le32_to_cpup(const __le32 *p) > | ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:60:8: error: unknown type name '__always_inline' > 60 | static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:60:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le16p' > 60 | static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > | ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:64:8: error: unknown type name '__always_inline' > 64 | static __always_inline __u16 __le16_to_cpup(const __le16 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:64:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le16_to_cpup' > 64 | static __always_inline __u16 __le16_to_cpup(const __le16 *p) > | ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:68:8: error: unknown type name '__always_inline' > 68 | static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:68:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be64p' > 68 | static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > | ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:72:8: error: unknown type name '__always_inline' > 72 | static __always_inline __u64 __be64_to_cpup(const __be64 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:72:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be64_to_cpup' > 72 | static __always_inline __u64 __be64_to_cpup(const __be64 *p) > | ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:76:8: error: unknown type name '__always_inline' > 76 | static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:76:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be32p' > 76 | static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > | ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:80:8: error: unknown type name '__always_inline' > 80 | static __always_inline __u32 __be32_to_cpup(const __be32 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:80:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be32_to_cpup' > 80 | static __always_inline __u32 __be32_to_cpup(const __be32 *p) > | ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:84:8: error: unknown type name '__always_inline' > 84 | static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:84:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be16p' > 84 | static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > | ^~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:88:8: error: unknown type name '__always_inline' > 88 | static __always_inline __u16 __be16_to_cpup(const __be16 *p) > | ^~~~~~~~~~~~~~~ > /usr/include/linux/byteorder/little_endian.h:88:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be16_to_cpup' > 88 | static __always_inline __u16 __be16_to_cpup(const __be16 *p) > | ^~~~~~~~~~~~~~ > make[3]: *** [/git/linux/tools/build/Makefile.build:139: util] Error 2 > 9 117.31 alpine:3.12 : Ok gcc (Alpine 9.3.0) 9.3.0, Alpine clang version 10.0.0 (https://gitlab.alpinelinux.org/alpine/aports.git 7445adce501f8473efdb93b17b5eaf2f1445ed4c) > 10 124.70 alpine:edge : Ok gcc (Alpine 10.2.0) 10.2.0, Alpine clang version 10.0.1 > 11 72.02 alt:p8 : Ok x86_64-alt-linux-gcc (GCC) 5.3.1 20151207 (ALT p8 5.3.1-alt3.M80P.1), clang version 3.8.0 (tags/RELEASE_380/final) > 12 87.30 alt:p9 : Ok x86_64-alt-linux-gcc (GCC) 8.4.1 20200305 (ALT p9 8.4.1-alt0.p9.1), clang version 10.0.0 > 13 87.33 alt:sisyphus : Ok x86_64-alt-linux-gcc (GCC) 10.2.1 20201125 (ALT Sisyphus 10.2.1-alt2), clang version 10.0.1 > 14 70.23 amazonlinux:1 : Ok gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2), clang version 3.6.2 (tags/RELEASE_362/final) > 15 104.56 amazonlinux:2 : Ok gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-12), clang version 7.0.1 (Amazon Linux 2 7.0.1-1.amzn2.0.2) > 16 23.52 android-ndk:r12b-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease) > 17 21.96 android-ndk:r15c-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease) > 18 27.58 centos:6 : Ok gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23) > 19 33.35 centos:7 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44) > 20 98.93 centos:8 : Ok gcc (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5), clang version 10.0.1 (Red Hat 10.0.1-1.module_el8.3.0+467+cb298d5b) > 21 69.01 clearlinux:latest : Ok gcc (Clear Linux OS for Intel Architecture) 10.2.1 20201217 releases/gcc-10.2.0-643-g7cbb07d2fc, clang version 10.0.1 > 22 79.89 debian:8 : Ok gcc (Debian 4.9.2-10+deb8u2) 4.9.2, Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0) > Ugh, sorry for that. I'm reminded of: https://lore.kernel.org/lkml/20210113223609.3358812-1-irogers@google.com/ On a similar subject, a header file weirdness/rant I have is: tools/include/uapi/linux/bpf.h It includes: #include <linux/types.h> #include <linux/bpf_common.h> The include paths for perf are: -I${SRC_DIR}/tools/lib/perf/include -I${SRC_DIR}/tools/perf/util/include -I${SRC_DIR}/tools/perf/arch/x86/include -I${SRC_DIR}/tools/include/ -I${SRC_DIR}/tools/arch/x86/include/uapi -I${SRC_DIR}/tools/include/uapi -I${SRC_DIR}/tools/arch/x86/include/ -I${SRC_DIR}/tools/arch/x86/ -I${DST_DIR}/util -I${DST_DIR} -I${SRC_DIR}/tools/perf/util -I${SRC_DIR}/tools/perf -I${SRC_DIR}/tools/lib/ Note that tools/include is before tools/include/uapi and that linux/types.h is included with the directory name. From this the search order is given in: https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html "Directories specified with -I options are scanned in left-to-right order." So when perf includes linux/bpf.h the types.h is coming from tools/include/linux/types.h rather than tools/include/uapi/linux/types.h that normal logic would expect (prefer headers in the same directory). bpf_common.h is coming from the uapi directory. Thanks, Ian ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2] perf parse-events: Break out tracepoint and printing. 2021-02-04 1:21 ` Ian Rogers @ 2021-06-08 20:41 ` Ian Rogers 0 siblings, 0 replies; 8+ messages in thread From: Ian Rogers @ 2021-06-08 20:41 UTC (permalink / raw) To: Arnaldo Carvalho de Melo Cc: Peter Zijlstra, Ingo Molnar, Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim, LKML, Stephane Eranian On Wed, Feb 3, 2021 at 5:21 PM Ian Rogers <irogers@google.com> wrote: > > On Wed, Feb 3, 2021 at 4:58 PM Arnaldo Carvalho de Melo <acme@kernel.org> wrote: > > > > Em Wed, Feb 03, 2021 at 05:50:24PM -0300, Arnaldo Carvalho de Melo escreveu: > > > Em Wed, Feb 03, 2021 at 10:38:41AM -0800, Ian Rogers escreveu: > > > > On Wed, Feb 3, 2021 at 8:21 AM Arnaldo Carvalho de Melo <acme@kernel.org> > > > > wrote: > > > > > > > > > Em Tue, Feb 02, 2021 at 09:26:59PM -0800, Ian Rogers escreveu: > > > > > > Move print_*_events functions out of parse-events.c into a new > > > > > > print-events.c. Move tracepoint code into tracepoint.c or > > > > > > trace-event-info.c (sole user). This reduces the dependencies of > > > > > > parse-events.c and makes it more amenable to being a library in the > > > > > > future. > > > > > > Remove some unnecessary definitions from parse-events.h. Fix a > > > > > > checkpatch.pl warning on using unsigned rather than unsigned int. > > > > > > > > > > Thanks, applied. > > > > > > > > > > > > > Wow, cool :-) I wasn't sure about the macros in the headers. Are you > > > > staging these patches before pushing to your perf/core or using > > > > tmp.perf/core ? I know you mentioned a different approach. When I look at: > > > > > > > > https://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git/ > > > > > > > > I don't see anything newer than 9 days. > > > > > > Right, I'm collecting some more patches, will do build tests and push, > > > till then, lemme push tmp.perf/core with what I have. > > > > Strange, some intermediary versions of Alpine Linux are complaining, I'll continue tomorrow morning :-\ > > > > [perfbuilder@five ~]$ time dm > > Wed Feb 3 09:32:47 PM -03 2021 > > # export PERF_TARBALL=http://192.168.86.5/perf/perf-5.11.0-rc6.tar.xz > > # dm > > 1 72.90 alpine:3.4 : Ok gcc (Alpine 5.3.0) 5.3.0, clang version 3.8.0 (tags/RELEASE_380/final) > > 2 74.62 alpine:3.5 : Ok gcc (Alpine 6.2.1) 6.2.1 20160822, clang version 3.8.1 (tags/RELEASE_381/final) > > 3 76.69 alpine:3.6 : Ok gcc (Alpine 6.3.0) 6.3.0, clang version 4.0.0 (tags/RELEASE_400/final) > > 4 84.43 alpine:3.7 : Ok gcc (Alpine 6.4.0) 6.4.0, Alpine clang version 5.0.0 (tags/RELEASE_500/final) (based on LLVM 5.0.0) > > 5 84.17 alpine:3.8 : Ok gcc (Alpine 6.4.0) 6.4.0, Alpine clang version 5.0.1 (tags/RELEASE_501/final) (based on LLVM 5.0.1) > > 6 16.71 alpine:3.9 : FAIL gcc (Alpine 8.3.0) 8.3.0, Alpine clang version 5.0.1 (tags/RELEASE_502/final) (based on LLVM 5.0.1) > > from util/print-events.c:10: > > /usr/include/linux/swab.h:161:8: error: unknown type name '__always_inline' > > static __always_inline __u16 __swab16p(const __u16 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/swab.h:161:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab16p' > > static __always_inline __u16 __swab16p(const __u16 *p) > > ^~~~~~~~~ > > /usr/include/linux/swab.h:174:8: error: unknown type name '__always_inline' > > static __always_inline __u32 __swab32p(const __u32 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/swab.h:174:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab32p' > > static __always_inline __u32 __swab32p(const __u32 *p) > > ^~~~~~~~~ > > /usr/include/linux/swab.h:187:8: error: unknown type name '__always_inline' > > static __always_inline __u64 __swab64p(const __u64 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/swab.h:187:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab64p' > > static __always_inline __u64 __swab64p(const __u64 *p) > > ^~~~~~~~~ > > /usr/include/linux/swab.h:242:23: error: expected ';' before 'void' > > static __always_inline void __swab32s(__u32 *p) > > ^~~~~ > > ; > > /usr/include/linux/swab.h:255:23: error: expected ';' before 'void' > > static __always_inline void __swab64s(__u64 *p) > > ^~~~~ > > ; > > In file included from /usr/include/asm/byteorder.h:5, > > from /git/linux/tools/include/uapi/linux/perf_event.h:20, > > from util/print-events.c:10: > > /usr/include/linux/byteorder/little_endian.h:44:8: error: unknown type name '__always_inline' > > static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:44:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le64p' > > static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:48:8: error: unknown type name '__always_inline' > > static __always_inline __u64 __le64_to_cpup(const __le64 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:48:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le64_to_cpup' > > static __always_inline __u64 __le64_to_cpup(const __le64 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:52:8: error: unknown type name '__always_inline' > > static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:52:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le32p' > > static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:56:8: error: unknown type name '__always_inline' > > static __always_inline __u32 __le32_to_cpup(const __le32 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:56:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le32_to_cpup' > > static __always_inline __u32 __le32_to_cpup(const __le32 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:60:8: error: unknown type name '__always_inline' > > static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:60:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le16p' > > static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:64:8: error: unknown type name '__always_inline' > > static __always_inline __u16 __le16_to_cpup(const __le16 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:64:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le16_to_cpup' > > static __always_inline __u16 __le16_to_cpup(const __le16 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:68:8: error: unknown type name '__always_inline' > > static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:68:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be64p' > > static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:72:8: error: unknown type name '__always_inline' > > static __always_inline __u64 __be64_to_cpup(const __be64 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:72:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be64_to_cpup' > > static __always_inline __u64 __be64_to_cpup(const __be64 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:76:8: error: unknown type name '__always_inline' > > static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:76:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be32p' > > static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:80:8: error: unknown type name '__always_inline' > > static __always_inline __u32 __be32_to_cpup(const __be32 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:80:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be32_to_cpup' > > static __always_inline __u32 __be32_to_cpup(const __be32 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:84:8: error: unknown type name '__always_inline' > > static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:84:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be16p' > > static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:88:8: error: unknown type name '__always_inline' > > static __always_inline __u16 __be16_to_cpup(const __be16 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:88:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be16_to_cpup' > > static __always_inline __u16 __be16_to_cpup(const __be16 *p) > > ^~~~~~~~~~~~~~ > > make[3]: *** [/git/linux/tools/build/Makefile.build:139: util] Error 2 > > 7 16.31 alpine:3.10 : FAIL gcc (Alpine 8.3.0) 8.3.0, Alpine clang version 8.0.0 (tags/RELEASE_800/final) (based on LLVM 8.0.0) > > from util/print-events.c:10: > > /usr/include/linux/swab.h:161:8: error: unknown type name '__always_inline' > > static __always_inline __u16 __swab16p(const __u16 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/swab.h:161:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab16p' > > static __always_inline __u16 __swab16p(const __u16 *p) > > ^~~~~~~~~ > > /usr/include/linux/swab.h:174:8: error: unknown type name '__always_inline' > > static __always_inline __u32 __swab32p(const __u32 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/swab.h:174:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab32p' > > static __always_inline __u32 __swab32p(const __u32 *p) > > ^~~~~~~~~ > > /usr/include/linux/swab.h:187:8: error: unknown type name '__always_inline' > > static __always_inline __u64 __swab64p(const __u64 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/swab.h:187:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab64p' > > static __always_inline __u64 __swab64p(const __u64 *p) > > ^~~~~~~~~ > > /usr/include/linux/swab.h:242:23: error: expected ';' before 'void' > > static __always_inline void __swab32s(__u32 *p) > > ^~~~~ > > ; > > /usr/include/linux/swab.h:255:23: error: expected ';' before 'void' > > static __always_inline void __swab64s(__u64 *p) > > ^~~~~ > > ; > > In file included from /usr/include/asm/byteorder.h:5, > > from /git/linux/tools/include/uapi/linux/perf_event.h:20, > > from util/print-events.c:10: > > /usr/include/linux/byteorder/little_endian.h:44:8: error: unknown type name '__always_inline' > > static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:44:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le64p' > > static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:48:8: error: unknown type name '__always_inline' > > static __always_inline __u64 __le64_to_cpup(const __le64 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:48:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le64_to_cpup' > > static __always_inline __u64 __le64_to_cpup(const __le64 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:52:8: error: unknown type name '__always_inline' > > static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:52:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le32p' > > static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:56:8: error: unknown type name '__always_inline' > > static __always_inline __u32 __le32_to_cpup(const __le32 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:56:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le32_to_cpup' > > static __always_inline __u32 __le32_to_cpup(const __le32 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:60:8: error: unknown type name '__always_inline' > > static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:60:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le16p' > > static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:64:8: error: unknown type name '__always_inline' > > static __always_inline __u16 __le16_to_cpup(const __le16 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:64:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le16_to_cpup' > > static __always_inline __u16 __le16_to_cpup(const __le16 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:68:8: error: unknown type name '__always_inline' > > static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:68:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be64p' > > static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:72:8: error: unknown type name '__always_inline' > > static __always_inline __u64 __be64_to_cpup(const __be64 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:72:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be64_to_cpup' > > static __always_inline __u64 __be64_to_cpup(const __be64 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:76:8: error: unknown type name '__always_inline' > > static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:76:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be32p' > > static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:80:8: error: unknown type name '__always_inline' > > static __always_inline __u32 __be32_to_cpup(const __be32 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:80:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be32_to_cpup' > > static __always_inline __u32 __be32_to_cpup(const __be32 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:84:8: error: unknown type name '__always_inline' > > static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:84:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be16p' > > static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > > ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:88:8: error: unknown type name '__always_inline' > > static __always_inline __u16 __be16_to_cpup(const __be16 *p) > > ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:88:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be16_to_cpup' > > static __always_inline __u16 __be16_to_cpup(const __be16 *p) > > ^~~~~~~~~~~~~~ > > make[3]: *** [/git/linux/tools/build/Makefile.build:139: util] Error 2 > > 8 18.59 alpine:3.11 : FAIL gcc (Alpine 9.3.0) 9.3.0, Alpine clang version 9.0.0 (https://git.alpinelinux.org/aports f7f0d2c2b8bcd6a5843401a9a702029556492689) (based on LLVM 9.0.0) > > from util/print-events.c:10: > > /usr/include/linux/swab.h:161:8: error: unknown type name '__always_inline' > > 161 | static __always_inline __u16 __swab16p(const __u16 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/swab.h:161:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab16p' > > 161 | static __always_inline __u16 __swab16p(const __u16 *p) > > | ^~~~~~~~~ > > /usr/include/linux/swab.h:174:8: error: unknown type name '__always_inline' > > 174 | static __always_inline __u32 __swab32p(const __u32 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/swab.h:174:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab32p' > > 174 | static __always_inline __u32 __swab32p(const __u32 *p) > > | ^~~~~~~~~ > > /usr/include/linux/swab.h:187:8: error: unknown type name '__always_inline' > > 187 | static __always_inline __u64 __swab64p(const __u64 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/swab.h:187:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__swab64p' > > 187 | static __always_inline __u64 __swab64p(const __u64 *p) > > | ^~~~~~~~~ > > /usr/include/linux/swab.h:242:23: error: expected ';' before 'void' > > 242 | static __always_inline void __swab32s(__u32 *p) > > | ^~~~~ > > | ; > > /usr/include/linux/swab.h:255:23: error: expected ';' before 'void' > > 255 | static __always_inline void __swab64s(__u64 *p) > > | ^~~~~ > > | ; > > In file included from /usr/include/asm/byteorder.h:5, > > from /git/linux/tools/include/uapi/linux/perf_event.h:20, > > from util/print-events.c:10: > > /usr/include/linux/byteorder/little_endian.h:44:8: error: unknown type name '__always_inline' > > 44 | static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:44:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le64p' > > 44 | static __always_inline __le64 __cpu_to_le64p(const __u64 *p) > > | ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:48:8: error: unknown type name '__always_inline' > > 48 | static __always_inline __u64 __le64_to_cpup(const __le64 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:48:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le64_to_cpup' > > 48 | static __always_inline __u64 __le64_to_cpup(const __le64 *p) > > | ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:52:8: error: unknown type name '__always_inline' > > 52 | static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:52:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le32p' > > 52 | static __always_inline __le32 __cpu_to_le32p(const __u32 *p) > > | ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:56:8: error: unknown type name '__always_inline' > > 56 | static __always_inline __u32 __le32_to_cpup(const __le32 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:56:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le32_to_cpup' > > 56 | static __always_inline __u32 __le32_to_cpup(const __le32 *p) > > | ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:60:8: error: unknown type name '__always_inline' > > 60 | static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:60:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_le16p' > > 60 | static __always_inline __le16 __cpu_to_le16p(const __u16 *p) > > | ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:64:8: error: unknown type name '__always_inline' > > 64 | static __always_inline __u16 __le16_to_cpup(const __le16 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:64:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__le16_to_cpup' > > 64 | static __always_inline __u16 __le16_to_cpup(const __le16 *p) > > | ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:68:8: error: unknown type name '__always_inline' > > 68 | static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:68:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be64p' > > 68 | static __always_inline __be64 __cpu_to_be64p(const __u64 *p) > > | ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:72:8: error: unknown type name '__always_inline' > > 72 | static __always_inline __u64 __be64_to_cpup(const __be64 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:72:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be64_to_cpup' > > 72 | static __always_inline __u64 __be64_to_cpup(const __be64 *p) > > | ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:76:8: error: unknown type name '__always_inline' > > 76 | static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:76:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be32p' > > 76 | static __always_inline __be32 __cpu_to_be32p(const __u32 *p) > > | ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:80:8: error: unknown type name '__always_inline' > > 80 | static __always_inline __u32 __be32_to_cpup(const __be32 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:80:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be32_to_cpup' > > 80 | static __always_inline __u32 __be32_to_cpup(const __be32 *p) > > | ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:84:8: error: unknown type name '__always_inline' > > 84 | static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:84:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__cpu_to_be16p' > > 84 | static __always_inline __be16 __cpu_to_be16p(const __u16 *p) > > | ^~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:88:8: error: unknown type name '__always_inline' > > 88 | static __always_inline __u16 __be16_to_cpup(const __be16 *p) > > | ^~~~~~~~~~~~~~~ > > /usr/include/linux/byteorder/little_endian.h:88:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__be16_to_cpup' > > 88 | static __always_inline __u16 __be16_to_cpup(const __be16 *p) > > | ^~~~~~~~~~~~~~ > > make[3]: *** [/git/linux/tools/build/Makefile.build:139: util] Error 2 Hi Arnaldo, Did you ever get to the bottom of the build failure on this platform? If you have reproduction instructions perhaps I can take a look. Thanks, Ian > > 9 117.31 alpine:3.12 : Ok gcc (Alpine 9.3.0) 9.3.0, Alpine clang version 10.0.0 (https://gitlab.alpinelinux.org/alpine/aports.git 7445adce501f8473efdb93b17b5eaf2f1445ed4c) > > 10 124.70 alpine:edge : Ok gcc (Alpine 10.2.0) 10.2.0, Alpine clang version 10.0.1 > > 11 72.02 alt:p8 : Ok x86_64-alt-linux-gcc (GCC) 5.3.1 20151207 (ALT p8 5.3.1-alt3.M80P.1), clang version 3.8.0 (tags/RELEASE_380/final) > > 12 87.30 alt:p9 : Ok x86_64-alt-linux-gcc (GCC) 8.4.1 20200305 (ALT p9 8.4.1-alt0.p9.1), clang version 10.0.0 > > 13 87.33 alt:sisyphus : Ok x86_64-alt-linux-gcc (GCC) 10.2.1 20201125 (ALT Sisyphus 10.2.1-alt2), clang version 10.0.1 > > 14 70.23 amazonlinux:1 : Ok gcc (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2), clang version 3.6.2 (tags/RELEASE_362/final) > > 15 104.56 amazonlinux:2 : Ok gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-12), clang version 7.0.1 (Amazon Linux 2 7.0.1-1.amzn2.0.2) > > 16 23.52 android-ndk:r12b-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease) > > 17 21.96 android-ndk:r15c-arm : Ok arm-linux-androideabi-gcc (GCC) 4.9.x 20150123 (prerelease) > > 18 27.58 centos:6 : Ok gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23) > > 19 33.35 centos:7 : Ok gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44) > > 20 98.93 centos:8 : Ok gcc (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5), clang version 10.0.1 (Red Hat 10.0.1-1.module_el8.3.0+467+cb298d5b) > > 21 69.01 clearlinux:latest : Ok gcc (Clear Linux OS for Intel Architecture) 10.2.1 20201217 releases/gcc-10.2.0-643-g7cbb07d2fc, clang version 10.0.1 > > 22 79.89 debian:8 : Ok gcc (Debian 4.9.2-10+deb8u2) 4.9.2, Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0) > > > > Ugh, sorry for that. I'm reminded of: > https://lore.kernel.org/lkml/20210113223609.3358812-1-irogers@google.com/ > > On a similar subject, a header file weirdness/rant I have is: > tools/include/uapi/linux/bpf.h > > It includes: > #include <linux/types.h> > #include <linux/bpf_common.h> > > The include paths for perf are: > -I${SRC_DIR}/tools/lib/perf/include > -I${SRC_DIR}/tools/perf/util/include > -I${SRC_DIR}/tools/perf/arch/x86/include > -I${SRC_DIR}/tools/include/ > -I${SRC_DIR}/tools/arch/x86/include/uapi > -I${SRC_DIR}/tools/include/uapi > -I${SRC_DIR}/tools/arch/x86/include/ > -I${SRC_DIR}/tools/arch/x86/ > -I${DST_DIR}/util -I${DST_DIR} > -I${SRC_DIR}/tools/perf/util > -I${SRC_DIR}/tools/perf > -I${SRC_DIR}/tools/lib/ > > Note that tools/include is before tools/include/uapi and that > linux/types.h is included with the directory name. From this the > search order is given in: > https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html > "Directories specified with -I options are scanned in left-to-right order." > So when perf includes linux/bpf.h the types.h is coming from > tools/include/linux/types.h rather than > tools/include/uapi/linux/types.h that normal logic would expect > (prefer headers in the same directory). bpf_common.h is coming from > the uapi directory. > > Thanks, > Ian ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-06-08 20:41 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-02-03 5:26 [PATCH 1/2] perf trace-event-info: Rename for_each_event Ian Rogers 2021-02-03 5:26 ` [PATCH 2/2] perf parse-events: Break out tracepoint and printing Ian Rogers 2021-02-03 16:20 ` Arnaldo Carvalho de Melo 2021-02-03 19:02 ` Ian Rogers [not found] ` <CAP-5=fVFeT6YtXJGHX0OC1BCa121bTC+ER7XDVO2g5rr8DYfDw@mail.gmail.com> 2021-02-03 20:50 ` Arnaldo Carvalho de Melo 2021-02-04 0:58 ` Arnaldo Carvalho de Melo 2021-02-04 1:21 ` Ian Rogers 2021-06-08 20:41 ` Ian Rogers
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.