Skip to content

virtiofs: negotiate FUSE_MAX_PAGES for larger I/O requests#3447

Merged
benhillis merged 1 commit into
microsoft:mainfrom
benhillis:virtiofs-fuse-max-pages
May 12, 2026
Merged

virtiofs: negotiate FUSE_MAX_PAGES for larger I/O requests#3447
benhillis merged 1 commit into
microsoft:mainfrom
benhillis:virtiofs-fuse-max-pages

Conversation

@benhillis
Copy link
Copy Markdown
Member

@benhillis benhillis commented May 8, 2026

Add FUSE_MAX_PAGES to DEFAULT_FLAGS so the FUSE server advertises support for larger request sizes during FUSE_INIT negotiation.

Background

Without this flag, the Linux kernel uses FUSE_DEFAULT_MAX_PAGES_PER_REQ (32 pages = 128 KiB) as the maximum request size. With the flag, the kernel uses min(fuse_max_pages_limit, virtqueue_size - FUSE_HEADER_OVERHEAD) which — for our default virtqueue size of 256 — is 252 pages (~1008 KiB). This is an 8x increase in max request size, significantly reducing per-request overhead for sequential I/O.

Benchmark results

burette virtio-fs benchmark, 3 iterations each, comparing with and without FUSE_MAX_PAGES flag.

6.1 kernel

Metric Baseline With flag Delta
Sequential read 166 MiB/s 227 MiB/s +37%
Sequential write 101 MiB/s 161 MiB/s +59%
Random read IOPS 2231 1953 ~noise
Random write IOPS 2312 2376 ~noise

6.12 kernel

Metric Baseline With flag Delta
Sequential read 119 MiB/s 219 MiB/s +83%
Sequential write 93 MiB/s 156 MiB/s +68%
Random read IOPS 1757 1807 ~noise
Random write IOPS 2416 2376 ~noise

Random I/O is unaffected as expected — 4K blocks do not benefit from larger request sizes.

Notes

DEFAULT_MAX_PAGES (256) is intentionally left unchanged. The kernel clamps max_pages to min(fuse_max_pages_limit=256, virtqueue_size-4=252), so larger values have no effect with the current virtqueue size of 256. The gain comes entirely from negotiating the flag, which moves the kernel from 32 to 252 pages per request.

On Linux 6.18+, fuse_max_pages_limit becomes a runtime module parameter (previously a compile-time constant). To benefit from values beyond 252 in the future, we would also need to increase the virtqueue size.

Add FUSE_MAX_PAGES to DEFAULT_FLAGS so the FUSE server advertises
support for larger request sizes during FUSE_INIT negotiation.

Without this flag, the Linux kernel uses FUSE_DEFAULT_MAX_PAGES_PER_REQ
(32 pages = 128 KiB) as the maximum request size. With the flag, the
kernel uses min(fuse_max_pages_limit, virtqueue_size - 4) which is
typically 252 pages (~1008 KiB) — an ~8x increase in max request size.

This significantly reduces per-request overhead (virtio descriptor
setup, FUSE header parsing, context switches) for sequential I/O.

Benchmark results (burette virtio-fs, 3 iterations, vs baseline):
  Sequential read:  144 → 329 MiB/s  (+129%)
  Sequential write: 149 → 284 MiB/s  (+91%)
  Random read IOPS: 2323 → 2390      (within noise)
  Random write IOPS: 2954 → 3134     (within noise)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 8, 2026 21:45
@benhillis benhillis requested a review from a team as a code owner May 8, 2026 21:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the FUSE session’s default init negotiation flags so virtio-fs can negotiate larger per-request I/O sizes with Linux guests by advertising FUSE_MAX_PAGES during FUSE_INIT.

Changes:

  • Add FUSE_MAX_PAGES to the DEFAULT_FLAGS bitmask used for FUSE init negotiation.

Comment thread vm/devices/support/fs/fuse/src/session.rs
@ptrivedi
Copy link
Copy Markdown

LGTM! why the big difference between 6.1 and 6.12? something else likely changed in the subsystem for newer kernels making this flag more effective there?

@benhillis
Copy link
Copy Markdown
Member Author

Tested the max-pages PR on Windows with the HDV device against both the baseline and PR builds. The
PR shows broad I/O improvements, sequential throughput +25%, random IOPS +20 - 40%, and metadata
ops about 20%.

@benhillis benhillis merged commit c1105b4 into microsoft:main May 12, 2026
69 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants