From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=74.125.82.197 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794599624; b=kQevG0PRe8ldBbhOVZels3iHMw2rOL/dDc+Zd6o2dV4adMOgzhy4Dckn5LrzphpsD/39 cBRH0ay+SAoPwh/XYnGPfCBEB5LTHiw52R/D8YXiw6T8E2V68e67nOdPdVffrayPgR0LH VgfnCtnWxqbZHiORyGWo2BR27rdUQbJvDJc00pj3RhrpT+oZ8Pxqzk4Qw3KCgpsmotr/8 5kOPfsOE7ZQcgVaRc2n1c3EOEw6JFqQuwuVznjg9rimaRxCGPTgq55a2HXG1Mom3RCYGj 8R+alOQ7H99iBSW2ejmBAG5GUQGUA0NM2isR29kohPkip2TzOtV/P8xszpjZ2y93cRw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794599624; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Received:Date:In-Reply-To: Mime-Version:References:X-Mailer:Message-ID:Subject:From:To:Cc: Content-Type; bh=kfhrMsa4puJEq2NxLT5Hxuoaf4b0ucNLDbW3ALcX/Sk=; b=MMPKOsPsNujnLWw3RZ/3kbsNkzUEKcqznZgN3kPMollGjbQp9Ca5VUBy84b22zymBr0n 1JDnqUfvbbHG8MRnEvjO5ArYs5RPUIfKavAenNhSRefXzDK/4NlLDloK15BYelsaaWTN2 UEIA5nNX9mO+/cWSSfGLi1c+1ANljUCZ1M0zQt41FL+5U59oX6MnR6FcgOCKLFURgy2a4 8t5B5KGqctJ72A1IY7kCra9L6SJAlOMC+4CA+vgRer0FxXJmHBe9WmigP/d4XoBbESXoc zgMKUpRIXpRULPbmpfXl03+ZtRevuKOAqmnrRa/GOKI5KCA1kgUTMWwls8B2MtQFuiQ== 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=DUtwgLhe; arc=none smtp.remote-ip=74.125.82.197 Received: from mail-dy1-f197.google.com (mail-dy1-f197.google.com [74.125.82.197]) (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 0E670606A89F for ; Fri, 13 Nov 2026 19:53:43 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 0E670606A89F 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) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20260707 header.b=DUtwgLhe Received: by mail-dy1-f197.google.com with SMTP id 5a478bee46e88-30bcb065bfdso1728675eec.0 for ; Fri, 13 Nov 2026 11:53:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20260707; t=1794599623; x=1795204423; 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=kfhrMsa4puJEq2NxLT5Hxuoaf4b0ucNLDbW3ALcX/Sk=; b=DUtwgLheIFYl1WP8cjmPLtIoMd8gNadv7BuBZfeFPWltJwyODjztoeKWY0nuZbMXgS PQ9c7S59r44BLiQ1te1AquHsY/72mTlDHyo6D/6waczEEtQgZmesRLKQvM+Bz8IcU4Y3 GO5a7T9IP80E2Pzti8IaxecOOsMl4TMei4GTUWNXviSVuFylKQD4h55CkSqZQekWctaD vGthjSDOp6R51sj9B7rNveZIp43tHdyFyeoVTsojUrhieGPGWCI/rMvwmQLjPtGSfh/a A5XuhEwn712ckC3cK9CETHhTiByf+jIkDkl1r+LSKatmd3u7Gs5Oc2qEH/s2EM1v2wlW wQ3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1794599623; x=1795204423; 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=kfhrMsa4puJEq2NxLT5Hxuoaf4b0ucNLDbW3ALcX/Sk=; b=nC5uH929AaHwCCfZfZyl+ghw7njiYDrhAc5Y5GubFvrCbYllaQqbLQNOznSe/9ubzG u9ljQsgSVEhYAnZsrFPKi4E4H2F517Vry7V6Pm9fwCi2l+zGwOw2YOyDt9DEHQVegKhS S6GkLNAr9r2iQGyvlA4AKZM5XWAf8TEwmsxyykXYjiiSc0PWBUg/AOJqVLlGWSCBngEL H+l+Fdo6voDPWSuwQIht2VvLU/4mtmWXi/JRszOEb2UTHWLeS1EFj3MdIovmJvy/I1/1 qn4KSovWAW29ZDRTlI4Sd/8OxgLPGL0ESd/6UDIvJ+LpXPaZskcWFin1GCvnLvHmeYj4 ov4w== X-Forwarded-Encrypted: i=1; AL+hErGzsCw4po5fUEJXAVKooUmpt1ZnpyJvIp4RsUFpKuFd2X4QJ+9w0T1ohPscYUJonV+M/BTDbhIu/ZPdztA=@vger.kernel.org X-Gm-Message-State: APuU4Z8yM0tBbRDmojbBKNN78AMi91LSKAqhnxpilkKvCahcrEyzqWLT NijJY8ZEBnv694C6sNa0A2UnGAIyzpV7yCpAlNVd4lfL1lEcvyHDedsltLooz14VVd/mOMezuSI /aDBZWjNpGQ== X-Received: from dyr22.prod.google.com ([2002:a05:693c:4016:b0:359:72f9:2aab]) (user=irogers job=prod-delivery.src-stubby-dispatcher) by 2002:a05:693c:40c3:b0:370:1e50:a485 with SMTP id 5a478bee46e88-379679df0a1mr3558243eec.37.1794599622862; Fri, 13 Nov 2026 11:53:42 -0800 (PST) Date: Fri, 13 Nov 2026 11:53:07 -0800 In-Reply-To: <20261113195335.2865725-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: <20261113195335.2865725-1-irogers@google.com> X-Mailer: git-send-email 2.56.1.703.gf848ed807c-goog Message-ID: <20261113195335.2865725-3-irogers@google.com> Subject: [PATCH v2 02/30] perf script: Fix metrics computed from samples From: Ian Rogers To: Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Namhyung Kim , Jiri Olsa , Ian Rogers , Adrian Hunter , James Clark Cc: linux-perf-users@vger.kernel.org, linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" perf script -F metric computes metrics from the sum of sample periods of the events, but the computed values were wrong and the output was garbled: - perf_stat_process_counter() replaces each count with its delta from the previous raw count. As counts were left as deltas, the next sample computed negative deltas for the counts of all CPUs and threads other than the sample's. Restore the counts to the running totals after processing. - Metrics for all events were displayed after every sample. Only display the metrics associated with the sampled event. - The new_line callback started a metric line that the next metric started again. Each metric starts its own line, so make it a no-op. - The metric value was written to stdout rather than the event's output file. For example, with whitespace reduced: $ perf record -e '{cpu_core/instructions/,cpu_core/cycles/}:S' -a sleep 1 $ perf script -F comm,cpu,event,period,metric Before: perf [001] 2206 cpu_core/cycles/: perf [001] metric: 42972.00 tma_info_inst_mix_instructions perf [001] metric: perf [001] metric: 1.20 tma_info_thread_cpi perf [001] metric: perf [001] metric: 0.83 tma_info_thread_ipc perf [001] metric: 51762.00 tma_info_thread_clks perf [001] 804 cpu_core/instructions/: perf [001] metric: 18446744073709549568.00 tma_info_inst_mix_instructions After: perf [001] 2206 cpu_core/cycles/: perf [001] metric: 67668.00 tma_info_thread_clks perf [001] 804 cpu_core/instructions/: perf [001] metric: 46758.00 tma_info_inst_mix_instructions perf [001] metric: 1.45 tma_info_thread_cpi perf [001] metric: 0.69 tma_info_thread_ipc Before, the cpu_core/cycles/ sample is followed by the metrics of both events, such as tma_info_inst_mix_instructions that only uses the instructions event, rather than just tma_info_thread_clks. The CPI and IPC lines repeat the "perf [001] metric:" prefix as script_new_line() started a line that script_print_metric() started again. The following cpu_core/instructions/ sample shows tma_info_inst_mix_instructions as 18446744073709549568, a negative delta, as the counts of the other CPUs were left as deltas by the previous sample. The same deltas made the before tma_info_thread_clks value of 51762 too small. After, each sample is followed only by the metrics of the sampled event, one per line, and the metric values are computed from the running totals of the sample periods of all CPUs. Fixes: 4bd1bef8bba2 ("perf script: Allow computing 'perf stat' style metrics") Fixes: 3622990efaab ("perf script: Change metric format to use json metrics") Signed-off-by: Ian Rogers --- tools/perf/builtin-script.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index b6691ebb1b4e..c5a9651a197c 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -2340,18 +2340,14 @@ static void script_print_metric(struct perf_stat_config *config __maybe_unused, if (color) color_fprintf(mctx->fp, color, fmt, val); else - printf(fmt, val); + fprintf(mctx->fp, fmt, val); fprintf(mctx->fp, " %s\n", unit); } static void script_new_line(struct perf_stat_config *config __maybe_unused, - void *ctx) + void *ctx __maybe_unused) { - struct metric_ctx *mctx = ctx; - - perf_sample__fprintf_start(NULL, mctx->sample, mctx->thread, mctx->evsel, - PERF_RECORD_SAMPLE, mctx->fp); - fputs("\tmetric: ", mctx->fp); + /* Each metric is printed on its own line by script_print_metric(). */ } struct script_find_metrics_args { @@ -2524,7 +2520,6 @@ static void perf_sample__fprint_metric(struct thread *thread, }; struct perf_counts_values *count, *old_count; int cpu_map_idx, thread_map_idx, aggr_idx; - struct evsel *pos; if (!init_metrics) { /* One time initialization of stat_config and metric data. */ @@ -2593,14 +2588,23 @@ static void perf_sample__fprint_metric(struct thread *thread, /* Update the aggregated stats. */ perf_stat_process_counter(&stat_config, evsel); - /* Display all metrics. */ - evlist__for_each_entry(evsel->evlist, pos) { - cpu_aggr_map__for_each_idx(aggr_idx, stat_config.aggr_map) { - perf_stat__print_shadow_stats(&stat_config, pos, - aggr_idx, - &ctx); + /* + * Processing the counter replaced the counts with deltas from the + * previous raw counts. Restore the running totals so that only the + * next sample's period is added to the aggregated stats. + */ + for (unsigned int cpu_idx = 0; cpu_idx < perf_cpu_map__nr(evsel->core.cpus); cpu_idx++) { + for (int thread_idx = 0; + thread_idx < perf_thread_map__nr(evsel->core.threads); + thread_idx++) { + *perf_counts(evsel->counts, cpu_idx, thread_idx) = + *perf_counts(evsel->prev_raw_counts, cpu_idx, thread_idx); } } + + /* Display the metrics associated with the sampled event. */ + cpu_aggr_map__for_each_idx(aggr_idx, stat_config.aggr_map) + perf_stat__print_shadow_stats(&stat_config, evsel, aggr_idx, &ctx); } static bool show_event(struct perf_sample *sample, -- 2.56.1.703.gf848ed807c-goog