Repository navigation
vpage: fix free tracking, release partial maps, enable vpages on small-L2 (NVL-S) - #11303
Conversation
|
@harajend fyi - pls let me know if this helps. |
There was a problem hiding this comment.
🟡 Changes recommended
Region boundary handling still has edge-case bugs, and the new regression test does not detect the original leak.
3 open findings
What changed in this PR
Fixes vpage sizing and allocation tracking, including NVL-S support.
Changes:
- Prevents virtual-region size underflow.
- Cleans up partially mapped pages and fixes out-of-order frees.
- Adds an out-of-order free boot test.
| File | Description |
|---|---|
zephyr/lib/vpage.c |
Updates region sizing, cleanup, and allocation tracking. |
zephyr/test/vpage.c |
Adds an out-of-order free regression test. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
6115723 to
b6f127a
Compare
PR 11303: test resultsRun date: 2026-11-10 08:38 UTC Tested commit: 621fb80f143e865509373482d35cc38bde00de3a |
Tested commit This issue is not fixed. All playback/capture tests still fail on both Detailed analysis:CI failure: DSP firmware crash on NVL-S (regression vs. previously-reported bug)Tested commit Result: All playback/capture-dependent test cases fail on both boards with an Identical PC/backtrace/address on both boards → deterministic firmware bug, not This looks like a regression against a previously-filed bug, not a fixWe have an existing internal bug report ( In that prior report, the failure was graceful: With this PR, the same Hypothesis: this PR enables actually mapping/using the vpage region Suggested next stepPlease check the map-then-use ordering / error handling around |
|
This PR fails without Zephyr zephyrproject-rtos/zephyr#122801 . @lgirdwood I pushed a minimal/subset of this PR as #11323 -> just fixes the overflow and limits SOF to what is safe to do with current version of Zephyr drivers. |
Will get Claude to respin once Zephyr part merged. |
b6f127a to
81400fb
Compare
|
Respun onto current main (commits split per review) and added a DNM west.yml commit pinning zephyr to kv2019i's #122801 head (7280c15b8cff, one commit on top of the current pin) so CI picks up the uncached-alias fix via west. Will drop it and bump the pin when the Zephyr PR merges. Related: #11323 is the minimal subset. |
|
@lgirdwood Needs a rebase, dependencies should be merged now |
81400fb to
176682b
Compare
|
Rebased onto main (the overflow check from #11323 is now upstream, so commit 3 is reduced to enabling the small-L2 layout) and dropped the DNM west.yml commit, as the Zephyr fix is already in the pinned revision (76280bce2a05 contains 5d0c907ec5d). Needs a CI run on NVL-S to confirm. |
|
@lgirdwood There's no NVL-S in PR CI, so either you need to test this manually before merge, and/or merge and check next daily (there's NVL-S in daily). |
176682b to
b925b3b
Compare
kv2019i
left a comment
There was a problem hiding this comment.
Some more comments inline
| * region (or the end of virtual memory) and cap it below by the | ||
| * physical L2 left after the image, as vpages can never use more. | ||
| * Pages beyond physical L2 are accessed through the coherent alias | ||
| * too, which needs the Zephyr TLB driver to map the uncached alias. |
There was a problem hiding this comment.
The last sentence is not super useful. More useful would be to replace with a link to the Zephyr PR -- the main point is Zephyr had a bug in using addresses beyond physical L2 end.
There was a problem hiding this comment.
Done, the comment now points at the Zephyr PR (zephyrproject-rtos/zephyr#122801) and states the main point that using pages beyond physical L2 needs the uncached alias mapped.
| @@ -312,18 +296,39 @@ __cold static int vpage_init(void) | |||
| end = l2_end - CONFIG_LIBRARY_REGION_SIZE; | |||
There was a problem hiding this comment.
Not a blocker but I wonder if the vpages should go beyond l2_end in this case. IOW why limit vpages to physical L2 size in this case, if we already know Zephyr supports going beyond and we use it below for systems with smaller L2. IOW, shouldn't we size vpages based on a) physical L2 size and b) image size. vpages cannot be larger than a-b, but I don't see a need to limit otherwise.
There was a problem hiding this comment.
The only cap applied in the small-L2 branch is a) physical L2 minus b) the image size (L2 end - image end), i.e. exactly the bound you describe; beyond that the region extends up to the library base / end of virtual memory. I kept the first branch (everything fits in L2) as is to not change the layout of the other platforms. Happy to unify the two if you prefer, but that would move other platforms' vpage regions.
There was a problem hiding this comment.
My comment was specifically about the first branch. Given the code now "oversubscribes" vpage+libregion in case of a smaller L2, why not oversubscribe also in the generic case?
But agreed this is probably handled in a separate PR.
vpages_free_and_unmap() moved velems[num_elems_in_use], which is one past the last in-use element, over the released slot. Freeing a non-last allocation therefore left the last element outside the in-use count, so the next allocation overwrote its tracking entry and that allocation could never be freed, leaking its virtual and physical pages. Decrement the count first so the real last element is moved. Add a boot test that frees allocations out of order and checks that the pages can be reused. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The mm driver maps page by page and leaves the pages already mapped, and their physical pages, in place when a later page fails, e.g. when physical L2 is exhausted. vpage then freed the virtual blocks without unmapping them, leaking physical L2. Unmap any page of the failed range that is still mapped before freeing the virtual blocks. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
The vpage region size was computed as an unsigned subtraction. The overflow is now caught, but vpages are then simply disabled when the virtual heap and library regions do not fit in L2 together with the image, as on NVL-S (2MB L2). Those regions are only virtual address space backed on demand, and the Zephyr TLB driver now maps the uncached alias of pages beyond physical L2 too. When they do not fit, place the vpage region after the virtual heap, end it at the library base address (or the end of virtual memory), and cap it by the physical L2 left after the image, as vpages cannot use more than that. Disable vpages only if no page is left. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
b925b3b to
c0936fc
Compare
|
Pushed a fix for the review comments (rollback hunk restored, comment updated). Agreed that NVL-S needs a manual test before merge or a check in the next daily; I have not run it on NVL-S hardware, only compiled it. |
lgirdwood
left a comment
There was a problem hiding this comment.
Pls check we have a ztest for each vpage API and if any missing lets add them. We need to check for over commit, leakage and sparse/continuous mappings.
Add boot tests for vpage_alloc() and vpage_free(): - zero page allocation - alignment, contiguity and full read/write of a multi-page allocation - over commit: more than available, absurd sizes and exhausting all pages fail cleanly and consume nothing - leaks: repeated alloc/free of mixed sizes and orders returns every page, detected by comparing the largest allocatable block before and after - sparse maps: holes left by frees are reused by single pages, larger blocks never overlap live pages and data is never corrupted - invalid frees (NULL, unaligned, mid-allocation, double free) are rejected without disturbing valid allocations - exhausting the allocation tracking elements fails cleanly and recovers Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
Added a ztest commit. vpage has two APIs, vpage_alloc() and vpage_free(); the boot tests now cover: zero-page alloc, alignment/contiguity/read-write of multi-page blocks, over commit (more than available, absurd sizes, exhausting everything, nothing consumed on failure), leaks (mixed sizes/orders over many rounds, compared via the largest allocatable block before/after), sparse maps (holes reused, larger blocks never overlap live pages, no data corruption), invalid frees (NULL, unaligned, mid-allocation, double free) and exhausting the tracking elements. Compile-checked only; they have not been run on a DUT yet. |
| @@ -312,18 +296,39 @@ __cold static int vpage_init(void) | |||
| end = l2_end - CONFIG_LIBRARY_REGION_SIZE; | |||
There was a problem hiding this comment.
My comment was specifically about the first branch. Given the code now "oversubscribes" vpage+libregion in case of a smaller L2, why not oversubscribe also in the generic case?
But agreed this is probably handled in a separate PR.



Follow-up to the vpage overflow check that landed in 27eec27 (#11323). The Zephyr TLB driver now maps the uncached alias (zephyrproject-rtos/zephyr#122801, in the current west.yml pin), so vpages beyond physical L2 can be used on NVL-S.
velems[num_elems_in_use](one past the last element) was moved over the released slot, orphaning the last element and leaking its pages. Adds an out-of-order free boot test.Rebased onto main; the DNM west.yml commit is dropped since the Zephyr fix is already in the pin. vpage.c compiles for nvl-s; not yet run on NVL-S hardware, which is what the CI run should confirm. Draft.
🤖 Generated with Claude Code