Skip to content

Revert sparse snapshot blob writes (#1788) - #1898

Merged
danbugs merged 1 commit into
mainfrom
revert-sparse-snapshot-blob
Oct 8, 2026
Merged

danbugs merged 1 commit into
mainfrom
revert-sparse-snapshot-blob

Conversation

@danbugs

@danbugs danbugs commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

This reverts #1788 because sparse snapshot blobs slow down the first guest function call after a restore on Windows (WHP). Any blob written with FSCTL_SET_SPARSE costs about 35 ms extra on that first guest function call, even when the blob has no holes. Clearing the flag later doesn't fix it; only a dense rewrite does.

Replaces #1895, which was opened from a fork and hit the shorter CI timeouts.

This reverts commit 3ef1a36.

On Windows, a snapshot blob marked with FSCTL_SET_SPARSE is slow to map
under WHP. The first guest function call after restoring from it takes
about 35 ms longer than from a dense blob. Having the flag set is enough:
a blob with no holes and a single extent is just as slow, and clearing
the flag afterwards does not help. Only a fresh dense write does.

Signed-off-by: danbugs <danilochiarlone@gmail.com>
@danbugs danbugs added the C-bug For PRs that fix bugs label Oct 7, 2026
Copilot AI balanced review requested due to automatic review settings October 7, 2026 18:54
@danbugs
danbugs enabled auto-merge (squash) October 7, 2026 18:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Existing valid sparse blobs are reused without the dense rewrite needed to remove the Windows penalty.

1 open finding
What changed in this PR

Restores dense snapshot blob writes to avoid WHP restore latency.

Changes:

  • Removes sparse file writing and related tests.
  • Reduces Windows API features.
  • Removes the sparse writing changelog entry.
File Description
fsutil.rs Restores dense blob writes.
Cargo.toml Removes sparse file API features.
CHANGELOG.md Removes the reverted feature entry.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@hyperlight-gh-bot

Copy link
Copy Markdown

Benchmark Results

Measured commit: c399ac2e13cb
Baseline commit: 3ee2d4cb3cbf

kvm / amd (Linux) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 782.69 ns (➖ 1.00x slower)
vec_bytes 579.42 ns (➖ 1.01x faster)
373.55 µs (➖ 1.00x faster)

payload_allocation

slot_pool_segmented
262144 525.16 ns (➖ 1.00x slower)
65536 141.56 ns (➖ 1.00x faster)

sandboxes

create_initialized_and_drop
medium 81.17 ms (➖ 1.02x slower)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
7.74 ns (➖ 1.00x slower) 7.83 ns (➖ 1.02x slower) 7.88 ns (➖ 1.00x faster)

snapshot_files

load_snapshot_unverified
small 92.17 µs (➖ 1.03x slower)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 7.46 µs (➖ 1.02x slower) 7.32 µs (➖ 1.01x slower)
65536 2.06 µs (➖ 1.01x faster) 2.07 µs (➖ 1.02x faster)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 6.43 µs (➖ 1.02x slower) 6.33 µs (➖ 1.01x slower)
8192 1.06 µs (➖ 1.01x faster) 1.08 µs (➖ 1.01x slower)
262144 27.47 µs (➖ 1.02x slower)
kvm / intel (Linux) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 769.81 ns (➖ 1.15x slower)
vec_bytes 572.64 ns (➖ 1.11x slower)
753.73 µs (➖ 1.11x slower)

payload_allocation

slot_pool_segmented
262144 605.00 ns (➖ 1.20x slower)
65536 153.14 ns (➖ 1.13x slower)

sandboxes

create_initialized_and_drop
medium 82.61 ms (➖ 1.11x slower)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
7.81 ns (➖ 1.13x slower) 7.80 ns (➖ 1.13x slower) 7.82 ns (➖ 1.14x slower)

snapshot_files

load_snapshot_unverified
small 49.79 µs (➖ 1.10x slower)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 8.57 µs (➖ 1.09x slower) 8.62 µs (➖ 1.11x slower)
65536 2.41 µs (➖ 1.11x slower) 2.43 µs (➖ 1.11x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 7.92 µs (➖ 1.09x slower) 8.00 µs (➖ 1.04x slower)
8192 848.89 ns (➖ 1.05x slower) 814.09 ns (➖ 1.03x faster)
262144 35.74 µs (➖ 1.21x slower)
mshv3 / amd (Linux) (↗️ 1.58x)

Top improvements

  • function_call_codec/encode_control/vec_bytes — ↗️ 1.58x faster

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 922.04 ns (➖ 1.02x faster)
vec_bytes 703.20 ns (↗️ 1.58x faster)
373.28 µs (➖ 1.30x slower)

payload_allocation

slot_pool_segmented
262144 730.38 ns (➖ 1.01x faster)
65536 254.31 ns (➖ 1.30x slower)

sandboxes

create_initialized_and_drop
medium 59.28 ms (➖ 1.03x slower)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
9.73 ns (➖ 1.00x slower) 9.71 ns (➖ 1.00x faster) 9.67 ns (➖ 1.01x faster)

snapshot_files

load_snapshot_unverified
small 84.69 µs (➖ 1.00x slower)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 9.84 µs (➖ 1.09x faster) 8.78 µs (➖ 1.04x faster)
65536 2.28 µs (➖ 1.02x slower) 2.22 µs (➖ 1.10x faster)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 8.14 µs (➖ 1.00x faster) 8.10 µs (➖ 1.03x faster)
8192 1.29 µs (➖ 1.00x faster) 1.39 µs (➖ 1.04x slower)
262144 36.96 µs (➖ 1.01x slower)
mshv3 / intel (Linux) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 929.64 ns (➖ 1.01x faster)
vec_bytes 663.85 ns (➖ 1.01x faster)
701.44 µs (➖ 1.05x slower)

payload_allocation

slot_pool_segmented
262144 672.68 ns (➖ 1.13x slower)
65536 170.80 ns (➖ 1.02x slower)

sandboxes

create_initialized_and_drop
medium 83.40 ms (➖ 1.31x slower)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
9.61 ns (➖ 1.01x slower) 8.82 ns (➖ 1.13x faster) 8.81 ns (➖ 1.00x slower)

snapshot_files

load_snapshot_unverified
small 48.48 µs (➖ 1.06x slower)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 7.78 µs (➖ 1.00x faster) 7.78 µs (➖ 1.03x faster)
65536 2.27 µs (➖ 1.01x slower) 2.27 µs (➖ 1.00x faster)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 7.57 µs (➖ 1.01x slower) 7.54 µs (➖ 1.01x faster)
8192 881.98 ns (➖ 1.01x slower) 880.92 ns (➖ 1.01x slower)
262144 35.81 µs (➖ 1.12x faster)
hyperv-ws2025 / amd (Windows) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 1.15 µs (➖ 1.01x faster)
vec_bytes 760.35 ns (➖ 1.04x faster)
2.18 ms (➖ 1.03x slower)

payload_allocation

slot_pool_segmented
262144 793.69 ns (➖ 1.05x faster)
65536 227.86 ns (➖ 1.04x faster)

sandboxes

create_initialized_and_drop
medium 102.45 ms (➖ 1.10x slower)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
11.22 ns (➖ 1.11x slower) 10.57 ns (➖ 1.01x slower) 10.75 ns (➖ 1.06x slower)

snapshot_files

load_snapshot_unverified
small 732.70 µs (➖ 1.10x faster)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 8.68 µs (➖ 1.11x faster) 8.60 µs (➖ 1.24x faster)
65536 2.54 µs (➖ 1.06x slower) 2.55 µs (➖ 1.08x slower)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 9.07 µs (➖ 1.02x slower) 8.96 µs (➖ 1.06x faster)
8192 1.41 µs (➖ 1.05x slower) 1.37 µs (➖ 1.03x slower)
262144 48.40 µs (➖ 1.25x slower)
hyperv-ws2025 / intel (Windows) (➖ stable)

No benchmark improved or regressed.

Benchmark Results

function_call_codec

encode_control decode_vec_bytes_copy
byte_chunks 1.24 µs (➖ 1.24x slower)
vec_bytes 816.77 ns (➖ 1.26x slower)
3.07 ms (➖ 1.17x faster)

payload_allocation

slot_pool_segmented
262144 742.03 ns (➖ 1.10x slower)
65536 218.37 ns (➖ 1.14x slower)

sandboxes

create_initialized_and_drop
medium 112.59 ms (➖ 1.10x faster)

slot_pool

alloc_dealloc_1500 alloc_dealloc_4096 alloc_dealloc_128
10.29 ns (➖ 1.20x slower) 10.11 ns (➖ 1.20x slower) 10.63 ns (➖ 1.31x slower)

snapshot_files

load_snapshot_unverified
small 476.54 µs (➖ 1.11x faster)

virtq_readonly

slot_pool_segmented_fragmented slot_pool_segmented
262144 7.62 µs (➖ 1.14x faster) 7.72 µs (➖ 1.13x faster)
65536 2.33 µs (➖ 1.09x faster) 2.31 µs (➖ 1.09x faster)

virtq_readwrite

slot_pool_segmented_fragmented slot_pool_segmented
65536 8.54 µs (➖ 1.08x faster) 8.60 µs (➖ 1.15x faster)
8192 1.11 µs (➖ 1.01x faster) 1.18 µs (➖ 1.02x slower)
262144 42.27 µs (➖ 1.18x slower)

Reported by cargo ci bench-report --candidate run:37670356285 --baseline run:37551535479 --config-file bench_report.toml.

@ludfjig

ludfjig commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Why doesn't bot comment show an improvement on windows?

@danbugs

danbugs commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Why doesn't bot comment show an improvement on windows?

We don't have a benchmark in hyperlight-core that catches the regression. It was observed in hyperlight-unikraft.

@jprendes

jprendes commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Why doesn't bot comment show an improvement on windows?

also, it currently only shows the results for a subset of the benchmarks, due to the high variance of some benches (#1894 is trying to fix that)

@danbugs
danbugs merged commit 9fb41fc into main Oct 8, 2026
167 of 178 checks passed
@danbugs
danbugs deleted the revert-sparse-snapshot-blob branch October 8, 2026 07:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-bug For PRs that fix bugs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants