Linux Perf Users
 help / color / mirror / Atom feed
* [RFC PATCH v1 00/14] perf stat: Decouple and modularize metrics/events output printing API
@ 2026-05-22 22:33 Ian Rogers
  2026-05-22 22:33 ` [RFC PATCH v1 01/14] perf stat: Introduce core generic print traversal engine and header stubs Ian Rogers
                   ` (14 more replies)
  0 siblings, 15 replies; 45+ messages in thread
From: Ian Rogers @ 2026-05-22 22:33 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim, Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark,
	linux-kernel, linux-perf-users

This RFC patch series introduces a complete architectural refactoring to decouple
and modularize the event and metric output printing engine inside 'perf stat'.

======================
Background and Motivation
======================
Historically, 'perf stat' output printing was tightly coupled with data collection,
aggregation math, and metrics calculation. Formatting logic (Standard Console,
CSV, and JSON) was scattered across util/stat-display.c, featuring complex
switch-cases, temporal adjacency assumptions, and duplicated layout logic. Adding new
metrics, uncore PMUs, or topology-aware CPU aggregation modes could result in
accidental layout regressions. A recently reported regression was:
https://lore.kernel.org/linux-perf-users/20260513144906.557896-1-ak@linux.intel.com/

This patch series decouples the data-traversal and shadows-metric calculations from
the visual layout rendering, introducing a modular callback-driven print architecture.

======================
Decoupled Printing Strategy
======================
1. Format-Agnostic Traversal Driver (util/stat-print.c)
   The core display logic is abstracted into a generic traversal driver,
   perf_stat__print_cb(). This driver manages the CPU/thread/topology
   aggregation loops, resolves hybrid wildcard merges, filters default skipped uncore
   metrics, and calculates raw metrics. Once the data points are prepared,
   the driver streams them cleanly to the output formatting callbacks.

2. Type-Safe Callbacks Interface (struct perf_stat_print_callbacks)
   Output formats communicate with the driver using a streaming interface:
   - print_start(): Initializes format-private DOM states or buffers.
   - print_event(): Buffers or prints raw counter event details (val, ena, run).
   - print_metric(): Buffers or prints calculated shadow metric values and thresholds.
   - print_end(): Finalizes rendering, formats padding, and cleans up state structures.

3. Format-Specific Rendering Engines:
   - Standard Console (util/stat-print-std.c):
     Buffers events and nested metrics into standard-private DOM lists. It resolves
     default metric-group skipped headers, prepends formatted interval timestamps,
     aligns continuation rows dynamically using aggr_header_lens, and prints them
     cleanly in print_end().
   - CSV Printing (util/stat-print-csv.c):
     Buffers events and metrics into format-private queues, formatting rows
     separated by config->csv_sep. Corrects metrics continuation padding to print
     exactly 4 separators, ensuring column counts are strictly and visually valid.
   - Streaming JSON Printing (util/stat-print-json.c):
     Implements a highly optimized, 100% streaming, zero-allocation print engine
     that bypasses dynamic queues and metrics buffering completely! JSON objects
     and interval keys are formatted and streamed directly onto the output file
     descriptor, maximizing speed and eliminating heap allocation overhead.

4. Centralized Aggregation Prefix Formatting
   Duplicates in CPU/thread aggregation prefix rendering are completely eliminated
   by introducing shared generic helpers in stat-print.c:
   - perf_stat__get_aggr_key(): Resolves the JSON key name.
   - perf_stat__get_aggr_id_char(): Resolves the unified aggregation ID string
     (e.g. "S0-D0-C0", "comm-pid").
   This mathematically guarantees absolute structural and visual consistency across
   all formats (Standard console pads dynamically, CSV splits by separator, JSON
   injects key-value pairs).

5. Temporal Coupling Sanity Checks
   A strict temporal coupling constraint (that the traversal driver always invokes
   print_metric() callbacks synchronously and consecutively for the same PMU/event
   node immediately after its print_event() callback) is formally protected by
   adding a runtime evsel matching check inside both STD and CSV print engines:
   if (evsel != ps->current_event->evsel) abort_print();

======================
Verification and Testing
======================
All automated shell linters (stat+std_output.sh, stat+csv_output.sh,
stat+json_output.sh) have been extended to run their entire aggregation suites a
second time under the new printer flag (--new), passing with 100% success. The PMU
metrics value Python validation script and stat_metrics_values.sh have also been
extended with --new flag testing, ensuring complete mathematical correctness of
calculated metric values.

All files have been beautifully formatted, passing scripts/checkpatch.pl with
exactly 0 errors on C and header code paths!

======================
Next Steps
======================
We would highly appreciate reviews, comments, and feedback on this
decoupled output printing strategy. After sufficient use, and because
tools are sensitive to output formatting, the "--new" option can be
the default. We can then look to remove stat-display.c and
stat-shadow.c.

***

Ian Rogers (14):
  perf stat: Introduce core generic print traversal engine and header
    stubs
  perf stat: Implement standard console (STD) formatting callbacks
  perf stat: Extend STD output linter to test basic New API checks
  perf stat: Extend STD output linter to test core aggregation checks
  perf stat: Extend STD output linter to test advanced PMU checks
  perf stat: Extend STD output linter to test metric-only checks
  perf stat: Implement CSV formatting callbacks
  perf stat: Extend CSV output linter to test core aggregation checks
  perf stat: Extend CSV output linter to test advanced PMU and
    metric-only checks
  perf stat: Implement streaming JSON formatting callbacks
  perf stat: Extend JSON output linter to test core aggregation checks
  perf stat: Extend JSON output linter to test advanced PMU and
    metric-only checks
  perf stat: Add --new support to PMU metrics Python validator
  perf stat: Extend PMU metrics value linter to validate --new outputs

 tools/perf/builtin-stat.c                     | 261 ++++---
 .../tests/shell/lib/perf_metric_validation.py |  12 +-
 tools/perf/tests/shell/stat+csv_output.sh     |  22 +
 tools/perf/tests/shell/stat+json_output.sh    |  49 +-
 tools/perf/tests/shell/stat+std_output.sh     |  21 +
 tools/perf/tests/shell/stat_metrics_values.sh |  13 +-
 tools/perf/util/Build                         |   4 +
 tools/perf/util/stat-print-csv.c              | 527 +++++++++++++
 tools/perf/util/stat-print-json.c             | 338 ++++++++
 tools/perf/util/stat-print-std.c              | 739 ++++++++++++++++++
 tools/perf/util/stat-print.c                  | 487 ++++++++++++
 tools/perf/util/stat-print.h                  | 129 +++
 12 files changed, 2456 insertions(+), 146 deletions(-)
 create mode 100644 tools/perf/util/stat-print-csv.c
 create mode 100644 tools/perf/util/stat-print-json.c
 create mode 100644 tools/perf/util/stat-print-std.c
 create mode 100644 tools/perf/util/stat-print.c
 create mode 100644 tools/perf/util/stat-print.h

-- 
2.54.0.794.g4f17f83d09-goog


^ permalink raw reply	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2026-05-26  0:20 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-22 22:33 [RFC PATCH v1 00/14] perf stat: Decouple and modularize metrics/events output printing API Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 01/14] perf stat: Introduce core generic print traversal engine and header stubs Ian Rogers
2026-05-22 23:47   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 02/14] perf stat: Implement standard console (STD) formatting callbacks Ian Rogers
2026-05-22 22:54   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 03/14] perf stat: Extend STD output linter to test basic New API checks Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 04/14] perf stat: Extend STD output linter to test core aggregation checks Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 05/14] perf stat: Extend STD output linter to test advanced PMU checks Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 06/14] perf stat: Extend STD output linter to test metric-only checks Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 07/14] perf stat: Implement CSV formatting callbacks Ian Rogers
2026-05-22 23:01   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 08/14] perf stat: Extend CSV output linter to test core aggregation checks Ian Rogers
2026-05-22 22:59   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 09/14] perf stat: Extend CSV output linter to test advanced PMU and metric-only checks Ian Rogers
2026-05-22 22:48   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 10/14] perf stat: Implement streaming JSON formatting callbacks Ian Rogers
2026-05-22 23:02   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 11/14] perf stat: Extend JSON output linter to test core aggregation checks Ian Rogers
2026-05-22 22:53   ` sashiko-bot
2026-05-22 22:33 ` [RFC PATCH v1 12/14] perf stat: Extend JSON output linter to test advanced PMU and metric-only checks Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 13/14] perf stat: Add --new support to PMU metrics Python validator Ian Rogers
2026-05-22 22:33 ` [RFC PATCH v1 14/14] perf stat: Extend PMU metrics value linter to validate --new outputs Ian Rogers
2026-05-25 23:18 ` [RFC PATCH v2 00/14] perf stat: Decouple and modularize metrics/events output printing API Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 01/14] perf stat: Introduce core generic print traversal engine and header stubs Ian Rogers
2026-05-25 23:38     ` Arnaldo Carvalho de Melo
2026-05-25 23:48       ` Ian Rogers
2026-05-26  0:20         ` Arnaldo Carvalho de Melo
2026-05-25 23:18   ` [RFC PATCH v2 02/14] perf stat: Implement standard console (STD) formatting callbacks Ian Rogers
2026-05-25 23:49     ` Arnaldo Carvalho de Melo
2026-05-26  0:09       ` Ian Rogers
2026-05-25 23:53     ` sashiko-bot
2026-05-25 23:18   ` [RFC PATCH v2 03/14] perf stat: Extend STD output linter to test basic New API checks Ian Rogers
2026-05-25 23:39     ` Arnaldo Carvalho de Melo
2026-05-25 23:18   ` [RFC PATCH v2 04/14] perf stat: Extend STD output linter to test core aggregation checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 05/14] perf stat: Extend STD output linter to test advanced PMU checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 06/14] perf stat: Extend STD output linter to test metric-only checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 07/14] perf stat: Implement CSV formatting callbacks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 08/14] perf stat: Extend CSV output linter to test core aggregation checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 09/14] perf stat: Extend CSV output linter to test advanced PMU and metric-only checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 10/14] perf stat: Implement streaming JSON formatting callbacks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 11/14] perf stat: Extend JSON output linter to test core aggregation checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 12/14] perf stat: Extend JSON output linter to test advanced PMU and metric-only checks Ian Rogers
2026-05-25 23:18   ` [RFC PATCH v2 13/14] perf stat: Add --new support to PMU metrics Python validator Ian Rogers
2026-05-25 23:19   ` [RFC PATCH v2 14/14] perf stat: Extend PMU metrics value linter to validate --new outputs Ian Rogers
2026-05-25 23:53     ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox