From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=74.125.82.70 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793749571; b=hMSkqRYGSFkYBhlgEyEpgeYi76OHk0AeEK3fYlXO9W6bndomptUTuKEdaPnM/FRA8yFO eKn1DgyUm/jrh0Kb7cZ5vsEE8bUQiWAxuLUcXNI5EX9oDq/xFI+w255DjhOaXJuo9FTb0 0mTcWA/MRsbeGV6vLRij8+Jz2RPtJ+pzGTa+yxjimhvkoSGagDvMby7HC33/xEcbX4rXC vMC65wmts1jZf3amD028qz2wmrIeCzQpvy6rm02TbEtHoKFESQ7faXIL9aOVzeJrBiwxt BM+Yo98BWKDVIlRu2KTU9nBEPVi8bZ1YVuVsLoLclzy4l3wn5mXjIXCgVJ3Vrf4rvqA== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793749571; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Gm-Message-State:X-Received:Date:In-Reply-To:Mime-Version: References:X-Mailer:Message-ID:Subject:From:To:Cc:Content-Type; bh=BdNIDHXwQW7cVFtv3QOuCHu+O347LacODj9B7d52BFs=; b=z8ga1VoLpCov1DtrC3K1pz1D6nR1oPUzOFrifVTK0kDLLTmb+uE6m9zcBccDu/4iTSNb vNnn1nqjOFq7b7f577qVaDk1lTOhkGZJJjfdHh2jaAZQHcPNhTQYMLL0F8on7qb7ko60I vaYbrWanXzQClTxNyjy7v/cAbZTD4IMShnqXlmdF6SrExnaq+E3mAivCjCSPJ4HGh/LhT DYUukv7i4aIfYUM5yvXh57X1T96YWszcPi2wXYbJqU7+Ld+CpCGkmbhCqd5IwOIIpaz3t aLPde8FOAFEZy5GoArJAx5eWRd0vga+d5+GMJbJbwfzrFoOckZNcWW28lcsoKCaMxxw== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=google.com; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com; dkim=pass header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20260707 header.b=pzNh0oHa; arc=none smtp.remote-ip=74.125.82.70 Received: from mail-dl1-f70.google.com (mail-dl1-f70.google.com [74.125.82.70]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D779E606A33A for ; Tue, 3 Nov 2026 23:46:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org D779E606A33A Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--irogers.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20260707 header.b=pzNh0oHa Received: by mail-dl1-f70.google.com with SMTP id a92af1059eb24-1a2af4c8cbaso92891c88.0 for ; Tue, 03 Nov 2026 15:46:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20260707; t=1793749570; x=1794354370; darn=vger.kernel.org; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:from:to:cc:subject:date:message-id:reply-to :content-type; bh=BdNIDHXwQW7cVFtv3QOuCHu+O347LacODj9B7d52BFs=; b=pzNh0oHawxxuYImTRiw5FmGhtcpfUnvRAFRMuHMiy9xrFWnvzjZVLq55QHGT4dndxI gpsV+18coGL9CAhwFZpEvjNr4QMPEXnLV+Fd6lR5ddTFaCxRbwGmxFP4rbHHHA16nVOi /Lhlc04ALaJLr6LovVIF+JI/waT20kwAT3aHj0bU0QD/6tgE7wOBrEDPkMyvUsLGUGAA 7zAPEv5x7+GnSBAJj5zbrX2AWdCeyjwPHfnUwok3wR97Q/7xzt/XDyx5aaxN/3x0gTbp zU5+GYtXrxeKox+YiERcVW3sTcuNjuyjiWWwSrOdp602BgeV14LTX830QsO+IxZ6BrEo +Lxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1793749570; x=1794354370; h=content-type:cc:to:from:subject:message-id:references:mime-version :in-reply-to:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=BdNIDHXwQW7cVFtv3QOuCHu+O347LacODj9B7d52BFs=; b=GBUTOt3gTg/xxOeKwkG3Erxr6nE3Kvx4uDik+CcUaN97AP0vRztfcDNp2Un0TAKuxK NcJRFufugLT4XmJLIUzxeP+Xxd3iyFMxGv+RY0bfF2yGYZXEFhPSANFLyNJ+DffDk9sH lLeEmfPBx61gh67BH+JyfIjqecdtXSuvn46bwH3qaXLJWcIJ8VTgGFZNi+mCf3OSDS8/ FQ+5UhHE3sk6LeMN3uDtMZieIksvk5FAxSG0CnrtRz9wFdCuPM07PSVgk+PTjg9B/X3H I/BBjkKrub4dUqLH9imxcnEe2VcS4tJuNO3i42GzlSXS3W+xJt4HfXcj5/C32hbgbNZW FUGQ== X-Gm-Message-State: APuU4Z+UQouuRG8F8rKOTzJCtPdGaBcRNXk/uaL3s5V317KjfYV45CYr XShOdvhoC5oI785Wg02ndGQgRB9afrD9zhHHcAfM7xqVZKG1+BWNUjPwUJco4iIckhkvjWEbhcA OQ64LAH0nZA== X-Received: from dleh6.prod.google.com ([2002:a05:701b:4346:b0:196:8199:c26c]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:7022:7e0c:b0:14c:d8d9:9502 with SMTP id a92af1059eb24-1ac5a0b8a9amr21752968c88.14.1793749569476; Tue, 03 Nov 2026 15:46:09 -0800 (PST) Date: Tue, 3 Nov 2026 15:44:39 -0800 In-Reply-To: <20261103234502.1008382-1-irogers@google.com> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list Mime-Version: 1.0 References: <20261103234502.1008382-1-irogers@google.com> X-Mailer: git-send-email 2.56.0.385.gac671c819a-goog Message-ID: <20261103234502.1008382-24-irogers@google.com> Subject: [PATCH v1 23/41] perf stat report: Display metrics for recorded events From: Ian Rogers To: linux-perf-users@vger.kernel.org, Arnaldo Carvalho de Melo , Namhyung Kim Cc: linux-kernel@vger.kernel.org, Peter Zijlstra , Ingo Molnar , Jiri Olsa , Adrian Hunter , James Clark , Kan Liang , Dapeng Mi , Thomas Falcon , John Garry , Will Deacon , Leo Yan , Athira Rajeev , Thomas Richter , Ravi Bangoria , Sandipan Das , Ian Rogers Content-Type: text/plain; charset="UTF-8" perf stat report displays the recorded counts but not the metrics that perf stat record displayed, as metrics aren't recorded in the perf.data file. Inspect the recorded command line in struct perf_env and display the metrics requested on the perf stat record command line (or the default metrics when no events or metrics were explicitly specified), for example: $ perf stat record -M insn_per_cycle -a sleep 1 $ perf stat report ... 784,599,279 cpu_atom/cpu-cycles/ # 0.7 instructions insn_per_cycle 586,070,692 cpu_atom/instructions/ 776,737,361 cpu_core/cpu-cycles/ # 1.3 instructions insn_per_cycle 1,011,699,468 cpu_core/instructions/ 1.004467030 seconds time elapsed Also add --all-metrics (and the stat.all-metrics config option) to display all metrics whose events were recorded in the perf.data file, as well as -M/--metrics and --metric-only options to perf stat report. Set stat_config.system_wide from the recorded thread map as metrics such as CPUs_utilized depend upon it. Signed-off-by: Ian Rogers --- tools/perf/Documentation/perf-config.txt | 7 ++++ tools/perf/Documentation/perf-stat.txt | 5 +++ tools/perf/builtin-stat.c | 53 +++++++++++++++++++++--- tools/perf/util/config.c | 3 ++ tools/perf/util/stat.h | 1 + 5 files changed, 64 insertions(+), 5 deletions(-) diff --git a/tools/perf/Documentation/perf-config.txt b/tools/perf/Documentation/perf-config.txt index 6cff6f26af8d..906e59c7e9d5 100644 --- a/tools/perf/Documentation/perf-config.txt +++ b/tools/perf/Documentation/perf-config.txt @@ -713,6 +713,13 @@ stat.*:: (boolean) Change the default for "--big-num". To make "--no-big-num" the default, set "stat.big-num=false". + stat.all-metrics:: + (boolean) Change the default for "--all-metrics" in + "perf stat report" and "perf script". When true, all metrics + whose events were recorded in the data file are displayed rather + than only the metrics requested on the "perf stat record" + command line. + intel-pt.*:: intel-pt.cache-divisor:: diff --git a/tools/perf/Documentation/perf-stat.txt b/tools/perf/Documentation/perf-stat.txt index 8ea17da89976..7258ec280770 100644 --- a/tools/perf/Documentation/perf-stat.txt +++ b/tools/perf/Documentation/perf-stat.txt @@ -426,6 +426,11 @@ information at the boundary of the level 3 cache in the system. --per-core:: Aggregate counts per physical processor for system-wide mode measurements. +--all-metrics:: +Display all metrics that match the recorded events in the perf data file, +rather than only the metrics requested on the 'perf stat record' command line. +Default setting can be changed with "perf config stat.all-metrics=true". + -M:: --metrics:: Print metrics or metricgroups specified in a comma separated list. diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index f81192cec481..12004244af0e 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -2232,6 +2232,28 @@ static int process_stat_round_event(const struct perf_tool *tool __maybe_unused, struct perf_env *env = perf_session__env(session); const char **argv = env->cmdline_argv; int argc = env->nr_cmdline; + static bool metrics_added; + + if (!metrics_added) { + struct perf_thread_map *threads = evlist__core(session->evlist)->threads; + bool system_wide = !threads || perf_thread_map__pid(threads, /*idx=*/0) == -1; + + /* Metrics may use system_wide, such as for #target_cpu. */ + stat_config.system_wide = system_wide; + metricgroup__add_recorded_metrics(session->evlist, metrics, + parse_events_option_args.pmu_filter, + parse_events_option_args.cputype_filter, + stat_config.metric_no_group, + stat_config.metric_no_merge, + stat_config.metric_no_threshold, + stat_config.all_metrics, + system_wide, + /*default_metricgroup=*/true, + force_metric_only ? NULL + : &stat_config.metric_only); + zfree(&metrics); + metrics_added = true; + } process_counters(); @@ -2282,6 +2304,8 @@ int process_stat_config_event(const struct perf_tool *tool, static int set_maps(struct perf_stat *st) { + struct evsel *counter; + if (!st->cpus || !st->threads) return 0; @@ -2293,6 +2317,9 @@ static int set_maps(struct perf_stat *st) if (evlist__alloc_stats(&stat_config, evsel_list, /*alloc_raw=*/true)) return -ENOMEM; + evlist__for_each_entry(evsel_list, counter) + counter->supported = false; + st->maps_allocated = true; return 0; } @@ -2351,7 +2378,7 @@ static int __cmd_report(int argc, const char **argv) { struct perf_session *session; struct opt_aggr_mode opt_mode = {}; - const struct option options[] = { + struct option options[] = { OPT_STRING('i', "input", &input_name, "file", "input file name"), OPT_BOOLEAN(0, "per-thread", &opt_mode.thread, "aggregate counts per thread"), OPT_BOOLEAN(0, "per-socket", &opt_mode.socket, @@ -2367,11 +2394,20 @@ static int __cmd_report(int argc, const char **argv) OPT_BOOLEAN(0, "per-node", &opt_mode.node, "aggregate counts per numa node"), OPT_BOOLEAN('A', "no-aggr", &opt_mode.no_aggr, "disable aggregation across CPUs or PMUs"), + OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list", + "display specified metrics or metric groups (separated by ,)", + append_metric_groups), + OPT_BOOLEAN(0, "all-metrics", &stat_config.all_metrics, + "display all metrics matching recorded events"), + OPT_CALLBACK_NOOPT(0, "metric-only", &stat_config.metric_only, NULL, + "Only print computed metrics. No raw values", + enable_metric_only), OPT_END() }; struct stat st; int ret; + set_option_flag(options, 'M', "metrics", PARSE_OPT_NONEG); argc = parse_options(argc, argv, options, stat_report_usage, 0); perf_stat.aggr_mode = opt_aggr_mode_to_aggr_mode(&opt_mode); @@ -2398,8 +2434,10 @@ static int __cmd_report(int argc, const char **argv) perf_stat.tool.stat_round = process_stat_round_event; session = perf_session__new(&perf_stat.data, &perf_stat.tool); - if (IS_ERR(session)) - return PTR_ERR(session); + if (IS_ERR(session)) { + ret = PTR_ERR(session); + goto out; + } perf_stat.session = session; stat_config.output = stderr; @@ -2408,10 +2446,13 @@ static int __cmd_report(int argc, const char **argv) ret = perf_session__process_events(session); if (ret) - return ret; + goto out; perf_session__delete(session); - return 0; +out: + /* Freed when processing the first stat round, if there was one. */ + zfree(&metrics); + return ret; } static void setup_system_wide(int forks) @@ -2589,6 +2630,8 @@ int cmd_stat(int argc, const char **argv) OPT_CALLBACK('M', "metrics", &evsel_list, "metric/metric group list", "monitor specified metrics or metric groups (separated by ,)", append_metric_groups), + OPT_BOOLEAN(0, "all-metrics", &stat_config.all_metrics, + "display all metrics matching recorded events (report only)"), OPT_BOOLEAN_FLAG(0, "all-kernel", &stat_config.all_kernel, "Configure all used events to run in kernel space.", PARSE_OPT_EXCLUSIVE), diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 287401f159e6..d64d0db51d8e 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -514,6 +514,9 @@ static int perf_stat_config(const char *var, const char *value) if (!strcmp(var, "stat.bpf-counter-events")) evsel__bpf_counter_events = strdup(value); + if (!strcmp(var, "stat.all-metrics")) + stat_config.all_metrics = perf_config_bool(var, value); + /* Add other config variables here. */ return 0; } diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h index e3598037a6aa..a957479804c1 100644 --- a/tools/perf/util/stat.h +++ b/tools/perf/util/stat.h @@ -82,6 +82,7 @@ struct perf_stat_config { bool metric_no_group; bool metric_no_merge; bool metric_no_threshold; + bool all_metrics; bool hardware_aware_grouping; bool stop_read_counter; bool iostat_run; -- 2.56.0.385.gac671c819a-goog