linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] perf jevents: Block-indexed string compression and default JEVENTS_ARCH=all
@ 2026-11-13 21:08 Ian Rogers
  2026-11-13 21:08 ` [PATCH 01/10] perf jevents: Store raw bytes in BigCString instead of C-escaped strings Ian Rogers
                   ` (9 more replies)
  0 siblings, 10 replies; 21+ messages in thread
From: Ian Rogers @ 2026-11-13 21:08 UTC (permalink / raw)
  To: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Namhyung Kim
  Cc: Jiri Olsa, Adrian Hunter, James Clark, Kan Liang,
	linux-perf-users, linux-kernel, Ian Rogers

Compiled-in PMU event and metric tables (pmu-events-in.o) currently
store ~6.9 MiB of uncompressed string data in .rodata on x86 alone,
causing JEVENTS_ARCH to default to $(SRCARCH) rather than all and
preventing out-of-the-box cross-architecture perf.data event/metric
resolution unless explicitly built with JEVENTS_ARCH=all.

Compressing big_c_string as a single whole-table stream would force perf
to allocate and decompress megabytes of unused CPU models' strings on
startup just to resolve a single event, whereas compressing individual
short strings suffers from poor compression ratios and per-string
framing overhead.

Instead, this series introduces "block-indexed string compression":
sorted, suffix-folded event and metric byte records are packed into
~8 KiB blocks without splitting records across block boundaries, each
block is compressed independently (sharing a single preset or trained
dictionary across blocks so ~8 KiB blocks retain high compression
ratios), and every uint32_t string offset is encoded as
(block_id << 16) | sub_offset. An ~8 KiB target block size sits at the
knee of the compression vs. random-access curve (smaller 1-4 KiB blocks
pay 22-128% more .rodata for per-block entropy headers and index
entries, while larger 16-64 KiB blocks yield <15% extra savings at 2-8x
higher decompression and page-fault cost per binary-search probe). At
runtime, pmu_events__get_string() uses a lock-free atomic block pointer
cache to decompress only the touched ~8 KiB blocks on demand, leaving
untouched CPU models' and non-host architectures' blocks compressed in
.rodata at zero runtime CPU or heap cost.

The series starts with a standalone BigCString raw-byte fix for
describe_metricgroup() binary-search ordering, prepares the string and
PMU table layout, adds the zlib, lzma, and zstd block compression
backends, and switches the default JEVENTS_ARCH to all:

- Bug fix, string layout, and hot-path isolation (Patches 1-4):
  - Patch 1 stores raw NUL-delimited UTF-8 bytes in BigCString instead
    of C-escaped strings, fixing suffix folding and describe_metricgroup()
    binary-search ordering on prefix-overlapping names (such as "Bad" vs
    "BadSpec"; Fixes: 66c6e0c10027) without changing empty-pmu-events.c
    so it can be cherry-picked standalone.
  - Patch 2 partitions non-folded BigCString event strings before metric
    strings and sorts entries lexicographically by their raw UTF-8 byte
    sequence within each partition so identically prefixed event names,
    encodings, descriptions, and metric expressions cluster into
    adjacent ~8 KiB blocks, improving block compression ratios by
    ~20-23%.
  - Patch 3 stores PMU names directly as const char *pmu_name string
    literals in struct pmu_table_entry (only 68 unique PMU names / 536 B
    across ~443 rows across all architectures, already in .data.rel.ro)
    so the compiler/linker merge them in .rodata.str1.1 and hot PMU
    wildcard scans never touch big_c_string or trigger block
    decompression.
  - Patch 4 encapsulates big_c_string offset lookups behind
    pmu_events__get_string(uint32_t offset) across pmu-events.c and
    pmu-events-string.c.
- On-demand block decompression backends (Patches 5-8):
  - Patch 5 packs big_c_string into ~8 KiB record-aligned blocks indexed
    by (block_id << 16) | sub_offset, adds lock-free thread-safe atomic
    per-block decompression on demand, and adds --compress=zlib using
    raw Deflate with a <= 32 KiB preset dictionary.
  - Patch 6 adds --compress=lzma using raw LZMA2 per block with a 64 KiB
    dictionary window.
  - Patch 7 adds --compress=zstd using ZSTD_decompress_usingDDict() per
    block with a once-digested shared 64 KiB ZSTD_DDict (~26% smaller
    .rodata than dictionary-free ~8 KiB zstd blocks).
  - Patch 8 wires JEVENTS_COMPRESS into Makefile.perf and
    pmu-events/Build, preferring zstd, then zlib, then lzma, and falling
    back to none.
- Testing and JEVENTS_ARCH=all default (Patches 9-10):
  - Patch 9 adds prefix-overlapping metricgroups.json test coverage and
    an 8-thread concurrent event/metric/metricgroup stress test in
    perf test pmu-events.
  - Patch 10 switches the default JEVENTS_ARCH to all. Bundling all
    architectures (x86, arm64, powerpc, riscv, s390, nds32) with zstd
    shrinks pmu-events-in.o from 7.16 MiB (x86 + none) to 1.11 MiB
    (all + zstd, -84.5%) and cuts the stripped perf binary from
    13.32 MiB to 7.28 MiB (-45.4%), with ~3 ms median wall-clock
    overhead on 'perf stat true'.

AI Assistance Disclosure (per Documentation/process/coding-assistants.rst
and Documentation/process/generated-content.rst):
- Tools used: Antigravity coding assistant and Sashiko automated patch
  review.
- Summary of prompts and assistance: Interactive design and
  implementation of the BigCString raw-byte fix and alphabetical
  sorting, struct pmu_table_entry PMU name string literals, lock-free
  8 KiB block-indexed decompression across zlib, lzma, and zstd,
  Makefile.config/Build integration, multithreaded unit tests,
  size/latency benchmarking, and Sashiko review fixes.
- Testing performed: Built and tested JEVENTS_COMPRESS={none,zlib,lzma,zstd}
  and NO_JEVENTS=1, JEVENTS_ARCH={x86,all}, AddressSanitizer +
  LeakSanitizer, perf test (pmu-events, make, metric parsing), and
  scripts/checkpatch.pl.

Ian Rogers (10):
  perf jevents: Store raw bytes in BigCString instead of C-escaped
    strings
  perf jevents: Sort BigCString entries alphabetically
  perf jevents: Store PMU names as string literals in struct
    pmu_table_entry
  perf jevents: Encapsulate big_c_string lookups behind
    pmu_events__get_string()
  perf jevents: Add block-indexed string packing and --compress=zlib
  perf jevents: Add --compress=lzma block compression backend
  perf jevents: Add --compress=zstd block compression backend
  perf build: Enable jevents string compression when available
  perf tests pmu-events: Test metricgroup descriptions and concurrent
    lookups
  perf build: Default JEVENTS_ARCH to all

 tools/perf/.gitignore                         |    1 +
 tools/perf/Makefile.config                    |    9 +-
 tools/perf/Makefile.perf                      |   13 +-
 tools/perf/pmu-events/Build                   |   49 +-
 .../arch/test/test_soc/cpu/metricgroups.json  |    4 +
 tools/perf/pmu-events/empty-pmu-events.c      | 7804 +++++++++--------
 tools/perf/pmu-events/jevents.py              |  967 +-
 tools/perf/tests/make                         |    5 +-
 tools/perf/tests/pmu-events.c                 |  209 +-
 9 files changed, 5015 insertions(+), 4046 deletions(-)
 create mode 100644 tools/perf/pmu-events/arch/test/test_soc/cpu/metricgroups.json


base-commit: 4af65363b11fc4fe65fcb497f68bbe4f3e3a4d2c
-- 
2.56.1.703.gf848ed807c-goog

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

end of thread, other threads:[~2026-11-13 21:21 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-13 21:08 [PATCH 00/10] perf jevents: Block-indexed string compression and default JEVENTS_ARCH=all Ian Rogers
2026-11-13 21:08 ` [PATCH 01/10] perf jevents: Store raw bytes in BigCString instead of C-escaped strings Ian Rogers
2026-11-13 21:21   ` sashiko-bot
2026-11-13 21:08 ` [PATCH 02/10] perf jevents: Sort BigCString entries alphabetically Ian Rogers
2026-11-13 21:12   ` sashiko-bot
2026-11-13 21:08 ` [PATCH 03/10] perf jevents: Store PMU names as string literals in struct pmu_table_entry Ian Rogers
2026-11-13 21:13   ` sashiko-bot
2026-11-13 21:08 ` [PATCH 04/10] perf jevents: Encapsulate big_c_string lookups behind pmu_events__get_string() Ian Rogers
2026-11-13 21:12   ` sashiko-bot
2026-11-13 21:08 ` [PATCH 05/10] perf jevents: Add block-indexed string packing and --compress=zlib Ian Rogers
2026-11-13 21:16   ` sashiko-bot
2026-11-13 21:08 ` [PATCH 06/10] perf jevents: Add --compress=lzma block compression backend Ian Rogers
2026-11-13 21:13   ` sashiko-bot
2026-11-13 21:08 ` [PATCH 07/10] perf jevents: Add --compress=zstd " Ian Rogers
2026-11-13 21:13   ` sashiko-bot
2026-11-13 21:08 ` [PATCH 08/10] perf build: Enable jevents string compression when available Ian Rogers
2026-11-13 21:17   ` sashiko-bot
2026-11-13 21:08 ` [PATCH 09/10] perf tests pmu-events: Test metricgroup descriptions and concurrent lookups Ian Rogers
2026-11-13 21:20   ` sashiko-bot
2026-11-13 21:08 ` [PATCH 10/10] perf build: Default JEVENTS_ARCH to all Ian Rogers
2026-11-13 21:21   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).