Stream: git-wasmtime

Topic: wasmtime / PR #14357 pooling allocator: complete the page...


view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2026 at 02:38):

HasanH47 opened PR #14357 from HasanH47:pagemap-reset-complete-traversal to bytecodealliance:main:

reset_with_pagemap collects dirty regions into a stack buffer of 32 and
treats the kernel's walk_end as the end of the memory it will ever reset
in place: everything after it is decommitted with madvise(DONTNEED).

Two consequences we hit running a QuickJS-based guest with a fresh
instance per request (pooling allocator, memory_init_cow, pagemap_scan):

  1. Throughput. A JS heap dirties far more than 32 disjoint runs, so
    the scan stopped early on every reset and the rest of the heap was
    decommitted. Each new instance then re-faulted its heap (95–315 minor
    faults per request measured with perf stat), and the madvise +
    mprotect storm capped multi-core scaling with TLB-shootdown IPIs.
    Resuming the scan from walk_end whenever the buffer filled, and
    stopping early only when the keep_resident page budget is spent (which
    is what walk_end is for), brought a request from 2.1 ms to 1.0 ms on
    one core and ×5 at 16 concurrent instances on a 16-core host, with 0
    faults per request.

  2. Freshness. The mask requires PRESENT. A dirty page the kernel has
    swapped out is WRITTEN | SWAPPED, not PRESENT; it is neither reset in
    place nor decommitted (it sits before walk_end), so the next instance in
    the slot reads the previous instance's bytes. We reproduced this with a
    swapfile and MADV_PAGEOUT between two instantiations of the same slot:
    the second instance observed the first's heap and trapped in the
    allocator. Requiring WRITTEN and not PFNZERO/FILE regardless of
    residency fixes it — resetting a swapped page pages it in and overwrites
    it, which is the cost of correctness. With 32 regions the accidental
    decommit of everything after walk_end hid most of this; with a complete
    traversal it would be exposed on every host with swap, so the two changes
    belong together.

The patch keeps the fixed stack buffer (64 regions) and loops the ioctl,
so there is still no allocation on the reset path. Unit tests in
pagemap.rs (they skip where PAGEMAP_SCAN is unavailable):

view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2026 at 02:38):

HasanH47 requested dicej for a review on PR #14357.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2026 at 02:38):

HasanH47 requested wasmtime-core-reviewers for a review on PR #14357.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2026 at 02:56):

HasanH47 updated PR #14357.

view this post on Zulip Wasmtime GitHub notifications bot (Sep 19 2026 at 04:46):

github-actions[bot] added the label wasmtime:api on PR #14357.


Last updated: Sep 20 2026 at 18:08 UTC