From e313beb668f41d49c10c546180fc02c62ab2cbe3 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 18 May 2024 20:48:00 +0200 Subject: Merging upstream version 6.7.12. Signed-off-by: Daniel Baumann --- tools/perf/Makefile.perf | 2 +- tools/perf/builtin-record.c | 35 +++++++---------------------------- tools/perf/builtin-top.c | 5 +++-- tools/perf/util/data.c | 2 -- tools/perf/util/evlist.c | 25 +++++++++++++++++++++++++ tools/perf/util/evlist.h | 1 + tools/perf/util/evsel.c | 1 - tools/perf/util/expr.c | 20 +++++++++++++++++++- tools/perf/util/pmu.c | 19 ++++++++++++++----- tools/perf/util/print-events.c | 27 +++++++++++++++++++-------- tools/perf/util/srcline.c | 2 ++ tools/perf/util/stat-display.c | 2 +- tools/perf/util/stat-shadow.c | 7 +------ tools/perf/util/thread_map.c | 2 +- 14 files changed, 94 insertions(+), 56 deletions(-) (limited to 'tools/perf') diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index 058c9aecf6..af22d539f3 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf @@ -1148,7 +1148,7 @@ bpf-skel: endif # CONFIG_PERF_BPF_SKEL bpf-skel-clean: - $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS) + $(call QUIET_CLEAN, bpf-skel) $(RM) -r $(SKEL_TMP_OUT) $(SKELETONS) $(SKEL_OUT)/vmlinux.h clean:: $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBSYMBOL)-clean $(LIBPERF)-clean arm64-sysreg-defs-clean fixdep-clean python-clean bpf-skel-clean tests-coresight-targets-clean $(call QUIET_CLEAN, core-objs) $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-iostat $(LANG_BINDINGS) diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index dcf288a4fb..5d86aa5ff5 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -1818,8 +1818,8 @@ static int record__switch_output(struct record *rec, bool at_exit) { struct perf_data *data = &rec->data; + char *new_filename = NULL; int fd, err; - char *new_filename; /* Same Size: "2015122520103046"*/ char timestamp[] = "InvalidTimestamp"; @@ -2216,32 +2216,6 @@ static void hit_auxtrace_snapshot_trigger(struct record *rec) } } -static void record__uniquify_name(struct record *rec) -{ - struct evsel *pos; - struct evlist *evlist = rec->evlist; - char *new_name; - int ret; - - if (perf_pmus__num_core_pmus() == 1) - return; - - evlist__for_each_entry(evlist, pos) { - if (!evsel__is_hybrid(pos)) - continue; - - if (strchr(pos->name, '/')) - continue; - - ret = asprintf(&new_name, "%s/%s/", - pos->pmu_name, pos->name); - if (ret) { - free(pos->name); - pos->name = new_name; - } - } -} - static int record__terminate_thread(struct record_thread *thread_data) { int err; @@ -2475,7 +2449,12 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) if (data->is_pipe && rec->evlist->core.nr_entries == 1) rec->opts.sample_id = true; - record__uniquify_name(rec); + if (rec->timestamp_filename && perf_data__is_pipe(data)) { + rec->timestamp_filename = false; + pr_warning("WARNING: --timestamp-filename option is not available in pipe mode.\n"); + } + + evlist__uniquify_name(rec->evlist); /* Debug message used by test scripts */ pr_debug3("perf record opening and mmapping events\n"); diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index ea8c7eca5e..cd64ae44cc 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -1027,8 +1027,8 @@ static int perf_top__start_counters(struct perf_top *top) evlist__for_each_entry(evlist, counter) { try_again: - if (evsel__open(counter, top->evlist->core.user_requested_cpus, - top->evlist->core.threads) < 0) { + if (evsel__open(counter, counter->core.cpus, + counter->core.threads) < 0) { /* * Specially handle overwrite fall back. @@ -1299,6 +1299,7 @@ static int __cmd_top(struct perf_top *top) } } + evlist__uniquify_name(top->evlist); ret = perf_top__start_counters(top); if (ret) return ret; diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c index c29d8a382b..550675ce0b 100644 --- a/tools/perf/util/data.c +++ b/tools/perf/util/data.c @@ -430,8 +430,6 @@ int perf_data__switch(struct perf_data *data, { int ret; - if (check_pipe(data)) - return -EINVAL; if (perf_data__is_read(data)) return -EINVAL; diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index b0ed14a6da..eb1dd29c53 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -2525,3 +2525,28 @@ void evlist__warn_user_requested_cpus(struct evlist *evlist, const char *cpu_lis } perf_cpu_map__put(user_requested_cpus); } + +void evlist__uniquify_name(struct evlist *evlist) +{ + struct evsel *pos; + char *new_name; + int ret; + + if (perf_pmus__num_core_pmus() == 1) + return; + + evlist__for_each_entry(evlist, pos) { + if (!evsel__is_hybrid(pos)) + continue; + + if (strchr(pos->name, '/')) + continue; + + ret = asprintf(&new_name, "%s/%s/", + pos->pmu_name, pos->name); + if (ret) { + free(pos->name); + pos->name = new_name; + } + } +} diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 98e7ddb2bd..cb91dc9117 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -442,5 +442,6 @@ struct evsel *evlist__find_evsel(struct evlist *evlist, int idx); int evlist__scnprintf_evsels(struct evlist *evlist, size_t size, char *bf); void evlist__check_mem_load_aux(struct evlist *evlist); void evlist__warn_user_requested_cpus(struct evlist *evlist, const char *cpu_list); +void evlist__uniquify_name(struct evlist *evlist); #endif /* __PERF_EVLIST_H */ diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 72a5dfc38d..1fb24ca8ae 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -2340,7 +2340,6 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event, data->period = evsel->core.attr.sample_period; data->cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; data->misc = event->header.misc; - data->id = -1ULL; data->data_src = PERF_MEM_DATA_SRC_NONE; data->vcpu = -1; diff --git a/tools/perf/util/expr.c b/tools/perf/util/expr.c index 7be23b3ac0..b8875aac8f 100644 --- a/tools/perf/util/expr.c +++ b/tools/perf/util/expr.c @@ -500,7 +500,25 @@ double expr__has_event(const struct expr_parse_ctx *ctx, bool compute_ids, const tmp = evlist__new(); if (!tmp) return NAN; - ret = parse_event(tmp, id) ? 0 : 1; + + if (strchr(id, '@')) { + char *tmp_id, *p; + + tmp_id = strdup(id); + if (!tmp_id) { + ret = NAN; + goto out; + } + p = strchr(tmp_id, '@'); + *p = '/'; + p = strrchr(tmp_id, '@'); + *p = '/'; + ret = parse_event(tmp, tmp_id) ? 0 : 1; + free(tmp_id); + } else { + ret = parse_event(tmp, id) ? 0 : 1; + } +out: evlist__delete(tmp); return ret; } diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index d3c9aa4326..aaa013af52 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -1019,10 +1019,9 @@ struct perf_pmu *perf_pmu__lookup(struct list_head *pmus, int dirfd, const char * type value and format definitions. Load both right * now. */ - if (pmu_format(pmu, dirfd, name)) { - free(pmu); - return NULL; - } + if (pmu_format(pmu, dirfd, name)) + goto err; + pmu->is_core = is_pmu_core(name); pmu->cpus = pmu_cpumask(dirfd, name, pmu->is_core); @@ -1756,6 +1755,12 @@ bool pmu__name_match(const struct perf_pmu *pmu, const char *pmu_name) bool perf_pmu__is_software(const struct perf_pmu *pmu) { + const char *known_sw_pmus[] = { + "kprobe", + "msr", + "uprobe", + }; + if (pmu->is_core || pmu->is_uncore || pmu->auxtrace) return false; switch (pmu->type) { @@ -1767,7 +1772,11 @@ bool perf_pmu__is_software(const struct perf_pmu *pmu) case PERF_TYPE_BREAKPOINT: return true; default: break; } - return !strcmp(pmu->name, "kprobe") || !strcmp(pmu->name, "uprobe"); + for (size_t i = 0; i < ARRAY_SIZE(known_sw_pmus); i++) { + if (!strcmp(pmu->name, known_sw_pmus[i])) + return true; + } + return false; } FILE *perf_pmu__open_file(const struct perf_pmu *pmu, const char *name) diff --git a/tools/perf/util/print-events.c b/tools/perf/util/print-events.c index b0fc48be62..4f67e8f00a 100644 --- a/tools/perf/util/print-events.c +++ b/tools/perf/util/print-events.c @@ -232,7 +232,6 @@ void print_sdt_events(const struct print_callbacks *print_cb, void *print_state) bool is_event_supported(u8 type, u64 config) { bool ret = true; - int open_return; struct evsel *evsel; struct perf_event_attr attr = { .type = type, @@ -246,20 +245,32 @@ bool is_event_supported(u8 type, u64 config) evsel = evsel__new(&attr); if (evsel) { - open_return = evsel__open(evsel, NULL, tmap); - ret = open_return >= 0; + ret = evsel__open(evsel, NULL, tmap) >= 0; - if (open_return == -EACCES) { + if (!ret) { /* - * This happens if the paranoid value + * The event may fail to open 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. - * + * 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; } + + if (!ret) { + /* + * The event may fail to open if the PMU requires + * exclude_guest to be set (e.g. as the Apple M1 PMU + * requires). + * Re-run with exclude_guest set; we don't do that by + * default as it's equally legitimate for another PMU + * driver to require that exclude_guest is clear. + */ + evsel->core.attr.exclude_guest = 1; + ret = evsel__open(evsel, NULL, tmap) >= 0; + } + evsel__delete(evsel); } diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index 034b496df2..7addc34afc 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -399,6 +399,8 @@ static void addr2line_subprocess_cleanup(struct child_process *a2l) kill(a2l->pid, SIGKILL); finish_command(a2l); /* ignore result, we don't care */ a2l->pid = -1; + close(a2l->in); + close(a2l->out); } free(a2l); diff --git a/tools/perf/util/stat-display.c b/tools/perf/util/stat-display.c index afe6db8e7b..969ce40096 100644 --- a/tools/perf/util/stat-display.c +++ b/tools/perf/util/stat-display.c @@ -560,7 +560,7 @@ static void print_metric_only(struct perf_stat_config *config, if (color) mlen += strlen(color) + sizeof(PERF_COLOR_RESET) - 1; - color_snprintf(str, sizeof(str), color ?: "", fmt, val); + color_snprintf(str, sizeof(str), color ?: "", fmt ?: "", val); fprintf(out, "%*s ", mlen, str); os->first = false; } diff --git a/tools/perf/util/stat-shadow.c b/tools/perf/util/stat-shadow.c index e314261678..cf573ff3fa 100644 --- a/tools/perf/util/stat-shadow.c +++ b/tools/perf/util/stat-shadow.c @@ -414,12 +414,7 @@ static int prepare_metric(struct evsel **metric_events, val = NAN; source_count = 0; } else { - /* - * If an event was scaled during stat gathering, - * reverse the scale before computing the - * metric. - */ - val = aggr->counts.val * (1.0 / metric_events[i]->scale); + val = aggr->counts.val; source_count = evsel__source_count(metric_events[i]); } } diff --git a/tools/perf/util/thread_map.c b/tools/perf/util/thread_map.c index e848579e61..ea3b431b97 100644 --- a/tools/perf/util/thread_map.c +++ b/tools/perf/util/thread_map.c @@ -280,13 +280,13 @@ struct perf_thread_map *thread_map__new_by_tid_str(const char *tid_str) threads->nr = ntasks; } out: + strlist__delete(slist); if (threads) refcount_set(&threads->refcnt, 1); return threads; out_free_threads: zfree(&threads); - strlist__delete(slist); goto out; } -- cgit v1.2.3