installed-fresh-desktop-20261024-next1 stopped after 1,104 s with exit
7: a RETYPE to ROZONE was refused because sprr_views_prepare found the
kernel views at SPRR_VIEW_TABLES (128). Its context.bin shows that 114
of the 118 level-3 copies still held selector2 leaves (122 ROZONE
protects, 3 releases): each RO-zone frame lands in its own 2 MiB table,
so the live set itself reached the pool. In the 86 preserved runs of
6 minutes or more, releases stayed at 2 to 8.
SNAP_VIEW_RECLAIM (opt-in, default 0):
- SPRR_VIEW_TABLES becomes 256. struct sprr_views grows by 8,192 bytes
and 65 of them precede pauth_bank, so PAUTH_BANK_CONTEXT moves under
the define (still asserted). The publication rows, the row-empty
checks (sprr_publish_row_empty) and USER_PUBLISH_MAX follow the
capacity. Context +1.0 MiB, root_ext +1.5 MiB of the arena.
- sprr_views_reclaim retires every copied table no CPU needs: a level-3
table without a valid selector2/4/9 leaf, an upper table none of
whose entries leads to a needed copy, never the root. It reads every
source before changing anything, compacts the metadata (kept tables
in order, retired sets parked past count at SPRR_VIEW_RETIRED), then
calls quiesce. kernel_views_quiesce drops the reuse snapshot and the
publication rows, and shadow_tlb_sync syncs all six views (a retired
table's parent entry names its canonical source again, an identical
translation), publishes them and runs TLBI ALLE1IS. Only after that
may add() reuse the six pages at that position; after a failed
quiesce they stay unusable.
The trigger is lazy: kernel_views_prepare_change, used by the ROZONE
and TXM-default retypes, reclaims only when a prepare is refused with
fewer than three free slots, then prepares the whole change again,
because the reclaim also retires paths an earlier leaf of the change
prepared (not protected until the commit). prepare_path refuses a path
that does not fit before adding any of it. Nothing runs before the pool
is full: the refresh, PPERM and sync paths are unchanged.
Off, the monitor is byte-identical: next1's flags give 458,552 bytes,
sha256 86bb02ea9e03...; so does the build without SNAP_EDP_BACKLIGHT
and the define-free one. On, the code grows by about 1.3 KiB, which
needs the code reservation of the next commit. kernel_sync_view's
frame grows from 2,336 to 4,528 bytes (64 KiB EL2 stacks; worst
direct-call chain 13.2 KiB, unchanged).
The mirrored multipage_close in tools/test-multipage-fast.c and the
source check in tools/test-kernel-ops-perf-source.py follow the row
helper. Hardware: not run.