test code v1
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# Pre9 LZMA cache review resolution
|
||||
|
||||
This document records the follow-up to commit `61f4709`, which cached one
|
||||
decoded LZMA extent per vnode.
|
||||
|
||||
## Findings addressed
|
||||
|
||||
- The cache is now one entry in `struct erofs_mount`, rather than one entry in
|
||||
every `struct erofs_node`. Retained decoded memory is bounded by one extent
|
||||
per mounted filesystem, with the number of mounts controlled by mount
|
||||
privileges. Keeping many ordinary file descriptors open cannot create more
|
||||
cache entries.
|
||||
- Cache initialization is performed in `erofs_mountfs()` immediately after
|
||||
mount allocation. `erofs_sb_free()` destroys it on every mount failure path
|
||||
and after successful `vflush()` during unmount. Node reclaim no longer owns
|
||||
cache cleanup.
|
||||
- `EROFS_MAP_META` is an explicit ineligibility condition. Metadata-backed
|
||||
tailpacking therefore remains on its existing read path.
|
||||
- `packed_inode` and `metabox_en` are explicit ineligibility conditions. The
|
||||
mount-private backing objects cannot populate or consume the user-data
|
||||
cache.
|
||||
- The cache type and helper names are now `erofs_zextent_cache` and
|
||||
`z_erofs_extent_cache_*`, distinguishing decoded extents from Linux's
|
||||
managed compressed-page cache names.
|
||||
- The key retains the existing physical/logical extent fields, device id,
|
||||
flags, and algorithm, and adds the stable inode `nid`. The `data` pointer is
|
||||
the validity bit, so NID zero is not treated as an empty key.
|
||||
|
||||
## Copy bound and concurrency
|
||||
|
||||
`z_erofs_read_uio()` limits each output request to `MAXPHYS`. The generic
|
||||
`z_erofs_read_data()` API can receive a larger request, so cache eligibility
|
||||
rejects any request whose mapped portion exceeds `MAXPHYS`. Both cache helper
|
||||
entry points also contain `KASSERT(len <= MAXPHYS)` checks. The largest copy
|
||||
performed while holding `z_extent_cache_lock` is therefore `MAXPHYS`; the
|
||||
12 MiB `Z_EROFS_PCLUSTER_MAX_DSIZE` limit remains an on-disk decoded-extent
|
||||
allocation bound, not a mutex-copy bound.
|
||||
|
||||
Allocation, compressed reads, and decompression happen outside the mutex. A
|
||||
cache hit copies while holding the mutex, and a miss publishes and copies
|
||||
under the same mutex before the previous allocation is freed. Concurrent
|
||||
misses may decode duplicate extents and may replace one another, but pointer
|
||||
access and replacement remain serialized. A refcounted immutable cache entry
|
||||
was deliberately not introduced in this first stage.
|
||||
|
||||
## Resource tradeoff
|
||||
|
||||
The per-mount entry is intentionally a small first-stage design. It removes
|
||||
the unbounded-per-open-vnode retention introduced by `61f4709`, but it can
|
||||
thrash when many files are read concurrently on one mount. Retention lasts
|
||||
until unmount, and the retained allocation is capped by the existing EROFS
|
||||
format constant `Z_EROFS_PCLUSTER_MAX_DSIZE` (12 MiB). A FreeBSD shrinker or
|
||||
pressure callback is deferred; adding one would require a broader memory
|
||||
accounting and lifecycle design than this corrective commit.
|
||||
|
||||
## Validation scope
|
||||
|
||||
This correction is statically validated only. QEMU validation remains
|
||||
required for complete SHA-256 reads, same-file concurrent reads, close/reopen,
|
||||
unmount cleanup, metadata tailpacking, and memory-pressure behavior. The
|
||||
existing Pre9 manual test report predates this correction and must not be
|
||||
reported as runtime validation of this commit.
|
||||
Reference in New Issue
Block a user