Repository navigation
openvmm: write each page of a new microVM RAM file once at capture - #797
Open
Pedro Henrique Penna (ppenna) wants to merge 1 commit into
Open
Pedro Henrique Penna (ppenna) wants to merge 1 commit into
Pedro Henrique Penna (ppenna) wants to merge 1 commit into
Conversation
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
The supplied evidence leaves source review and exact-pin Windows/WHP runtime validation pending for the memory-writeback change.
No open issues 🎉
What changed in this PR
This PR integrates OpenVMM’s Windows RAM-flush optimization into NVX, aiming to reduce snapshot-capture write amplification and timing variance. It builds on #788 and does not resolve the external storage stalls tracked by #169.
Changes:
- Documents the ascending flush pass and updated write-volume estimate for a 128 MiB guest.
- Records the new OpenVMM pin at position 338 and its planned fold into the existing sparse-memory upstream work.
| File | Description |
|---|---|
doc/openvmm-upstream-roadmap.md |
Records the new pin and position-338 fixup atop the v2.3 roadmap. |
doc/benchmarks.md |
Explains the reduced Windows capture writes and continued dependence on scratch-volume throughput. |
Review effort: Balanced
This was referenced Oct 23, 2026
Open
Pin microsoft/openvmm#4734 at 8a0d945edca13b301a5152f225702057337b2a56, one commit on 79a501b63, the head of feature/microvm/dev and feature/microvm/release/v2.3, which #788 pins. A Windows microVM capture flushes guest RAM to the backing file that OpenVMM creates at launch. NTFS zero-fills such a new file below any write past its valid data length, and OpenVMM flushed it with up to eight concurrent FlushViewOfFile calls over disjoint ranges, so ranges were written twice: a 128 MiB guest wrote about 135 to 180 MiB per capture, a different amount each time. That spread capture.mapped_memory_flush within a lifecycle series even on a steady scratch volume and left the stability check of #169 less margin for the volume's throughput. OpenVMM now marks every page of the RAM view modified and flushes it in one ascending pass, so a capture writes at most 128 MiB, and fragmented dirty pages no longer turn the flush into seconds of small writes. The runners measured the identical patch on 7ff31ed7a, the v2.2 pin. At CI's Windows acceptance settings with F: scratch, on azure-windows-1, -3, and -4, snapshot generation fell from a p50 of 1056 to 1188 ms to 836 to 878 ms, with every series' p50 within 1.2% of its p25, and cold boot and restore stayed within their run-to-run variation. Linux hosts are unaffected. The change does not remove the external trigger of #169: when another writer halves the scratch volume's throughput mid-series, the series of both builds still split and are rejected. doc/benchmarks.md said that a 128 MiB capture writes about 150 MiB; it now describes the single pass. The roadmap records the commit as position 338, a PR02 fixup to fold into position 010. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pedro Henrique Penna (ppenna)
force-pushed
the
agents/issue-169-investigation-fix-validation
branch
from
October 23, 2026 16:53
7e65d90 to
aaf30ed
Compare
Pedro Henrique Penna (ppenna)
added a commit
that referenced
this pull request
Oct 23, 2026
Pin microsoft/openvmm#4735 at 2b681564dd63483f2f9c9f9bba3b98a4c00e9680, two commits on 8a0d945ed, the head of microsoft/openvmm#4734 that #797 pins, which is one commit on 79a501b63, the head of feature/microvm/dev. The first commit lets a platform snapshot opt into restore-time vCPU activation. Restore-time memory expansion already worked on every tier, but a platform capture booted with maxcpus=B failed to publish, because the platform tier's command-line allowlist did not accept maxcpus=, and one captured without it refused --restore-processors at every restore. OpenVMM now accepts one maxcpus= token on a platform command line, the canonical form of the recorded boot-online count, as it accepts nr_cpus=, so each clone of one platform capture can bring its own vCPU prefix online at restore. The second stops the control-console broker from timing a host's authentication while host input is gated. A host that connected as soon as it launched a gated restore, and authenticated right away, was detached whenever the guest's repair outlasted --microvm-control-auth-timeout-ms, although the broker had not read its authentication yet. The timeout is now suspended while input is gated and restarts when the input is released. Part of #796 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pins microsoft/openvmm#4734 at
8a0d945edca13b301a5152f225702057337b2a56. With it, a Windows microVM capture writes each page of its new guest RAM file once, in one ascending pass. Refs #169: this removes a source of variance incapture.mapped_memory_flush, not the external storage trigger, so the issue stays open.#788 merged into
devat 11:03Z on 2026-10-23. This PR is now one commit,aaf30ed88, directly ondevat17f84bb60. It is7e65d9038, the commit originally stacked on #788's head, rebased without change:git range-diffreports an identical patch, and nodevcommit since #788 touchesopenvmm,doc/benchmarks.md, ordoc/openvmm-upstream-roadmap.md.Change
openvmm79a501b63→8a0d945ed: the single commit of microsoft/openvmm#4734 onfeature/microvm/devdoc/benchmarks.mddoc/openvmm-upstream-roadmap.mdWhy
On Windows, NTFS zero-fills a file below any write that starts past its valid data length. The RAM backing that OpenVMM creates for a microVM capture is new. OpenVMM flushed it with up to eight concurrent
FlushViewOfFilecalls over disjoint ranges (the bounded-concurrency flush that #171 brought in), so ranges that NTFS had zero-filled below a high write were written again. A 128 MiB guest wrote about 135–180 MiB per capture, a different amount each time. That spreadcapture.mapped_memory_flushwithin a lifecycle series even on a steady scratch volume. Fragmented dirty pages turned the flush into seconds of small writes: 7.7–25.8 s for alternating pages in a new 128 MiB file.OpenVMM now marks every page of the writable RAM view modified, without changing its contents, and flushes it in one ascending pass. Linux hosts are unaffected; the change is in
sparse_mmap's Windows module.Evidence
I took
azure-windows-1,-3, and-4out of the pool temporarily and ran CI's Windows acceptance benchmark on each at CI's settings: a 128 MiB guest, 1 vCPU, one warmup and ten samples, F: scratch. The runs interleaved CI's build, a local build of the same source, and the fix:Equivalence and validation
ae65298b4, the same change on7ff31ed7a, the v2.2 pin. It has the same patch-id as8a0d945ed(a22aec434) and the same blobs for both changed files. That is patch equivalence, not tree identity, because the bases differ.sparse_mmap:cargo check --all-targets,cargo clippy --all-targets,cargo doc --no-deps, andcargo nextest run --profile agent(21 passed, 2 skipped).cargo xtask fmt --fixmade no changes.python scripts\nvx.py verifyandscripts/check_markdown_links.pypass at this head.7e65d9038: run 39940877632, attempt 2, passed every job. Attempt 1 failed only because apowershell.exelaunch inNVX CLI / Windowsexceeded its 30 s test timeout on the hosted runner, which also skipped the WHP jobs.aaf30ed88, againstdevwith ci: shard the WHP OpenVMM VMM tests across two runners #803's sharded WHP VMM tests: run 39990548819 passed every job on its first attempt, including bothOpenVMM vmm-tests / Windows / WHPshards.Exact NVX head submitted to CI:
aaf30ed88d0c091ae955a660956055a66bff7452.Performance history
At
aaf30ed88, the WHP platform job on the benchmark runner, azure-windows-5, accepted its first lifecycle measurement. Snapshot generation had a p50 of 783.3 ms (732–868 ms), and every flush took 670–805 ms. That is 23% below the 10-point base median of 1021.1 ms (965–1108 ms) indata/windows-whp-virtual-machine-microvm-v2-1vcpu.csv. Cold start (p50 550.5 ms) and restore (150.5 ms) stayed at their base medians of 549.6 and 155.0 ms. At7e65d9038, the same job measured a snapshot-generation p50 of 755.6 ms. The gate treats lower values as improvements, so the history needs no reset.