Skip to content

Improve VirtioFs performance with swiotlb#40518

Closed
asherkariv wants to merge 3 commits into
masterfrom
user/askariv/swiotlb-enable
Closed

Improve VirtioFs performance with swiotlb#40518
asherkariv wants to merge 3 commits into
masterfrom
user/askariv/swiotlb-enable

Conversation

@asherkariv
Copy link
Copy Markdown

@asherkariv asherkariv commented May 13, 2026

Summary

Improve VirtioFs performance by adding swiotlb (Software Translation Lookaside Buffer) bounce buffer support for virtio devices. Swiotlb enables more efficient DMA handling for VirtioFs, reducing overhead in file system operations.

PR Checklist

  • Builds clean (Release x64)
  • Code review passed

Detailed Description

Commit 1: Add experimental.swiotlb .wslconfig setting

  • Adds a new [experimental] config key swiotlb to specify custom swiotlb configuration
  • Adds localization strings and validation

Commit 2: Swiotlb gating, vmId plumbing, and devicehost override

  • Swiotlb gating for VirtioFs perf: Automatically compute default swiotlb bounce buffer config when VirtioFs (or other virtio devices) are enabled, enabling efficient DMA for file system operations
  • Virtio9p deprecation ordering: Move the virtio9p deprecation/disable block before swiotlb computation so deprecated devices don't trigger unnecessary bounce buffer config
  • vmId plumbing: Inject vmId= into all virtio device options via \GuestDeviceManager::AddHdvShareWithOptions\ for proper device-to-VM association
  • WSL_DEVICE_HOST_DLL override: Add CMake option to replace wsldevicehost.dll without a NuGet update (dev-loop improvement)
  • Fix empty-options guard: Prevent double semicolons when appending to device options
  • Package update: Update packages.config

Validation Steps

  • Built successfully in Release x64 configuration
  • Code reviewed for logic correctness (swiotlb gating order verified)

Copilot AI review requested due to automatic review settings May 13, 2026 01:18
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

This PR introduces a new experimental .wslconfig key (experimental.swiotlb) to control SWIOTLB bounce buffer behavior for WSL VMs using virtio devices. The setting is validated during config parsing, optionally propagated to the guest kernel command line (range mode), and also forwarded to wsldevicehost.dll via a virtiofs “name-with-options” control token.

Changes:

  • Add experimental.swiotlb parsing/validation and store both a virtiofs token value (SwiotlbCfg) and an optional kernel cmdline value (SwiotlbKernelCfg).
  • Plumb SWIOTLB configuration into virtiofs share options and (range mode) append hv_pci_swiotlb= to the guest kernel command line.
  • Add new constants and localization strings for invalid-value and virtiofs-required warnings.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/windows/service/inc/wslservice.idl Adds LXSS_VM_KERNEL_SWIOTLB_CONFIG constant used when building the kernel cmdline.
src/windows/service/exe/WslCoreVm.cpp Appends SWIOTLB kernel parameter (range mode) and adds virtiofs control token in share options.
src/windows/common/WslCoreConfig.h Adds config key name and new config fields (SwiotlbCfg, SwiotlbKernelCfg) + telemetry presence bit.
src/windows/common/WslCoreConfig.cpp Implements experimental.swiotlb parsing/validation and enforces virtiofs dependency.
src/shared/inc/lxinitshared.h Adds LX_INIT_SWIOTLB_MOUNT_OPTIONS mount-option/control-token prefix.
localization/strings/en-US/Resources.resw Adds localized warning strings for invalid SWIOTLB and virtiofs-required cases.

Comment thread src/windows/common/WslCoreConfig.cpp Outdated
Comment thread src/windows/common/WslCoreConfig.cpp Outdated
Comment thread src/shared/inc/lxinitshared.h Outdated
Comment thread src/windows/common/WslCoreConfig.cpp
Comment thread src/windows/service/inc/wslservice.idl Outdated
Copilot AI review requested due to automatic review settings May 13, 2026 21:49
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

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread src/windows/common/WslCoreConfig.h Outdated
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

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Comment thread test/windows/UnitTests.cpp Outdated
@benhillis
Copy link
Copy Markdown
Member

I might be confused but I thought we didn’t need this setting until we have the updated kernel?

benhillis pushed a commit that referenced this pull request May 18, 2026
…n WSLC

A user-supplied WSL2 kernel without the WSL swiotlb patch ignores
hv_pci_swiotlb= but still receives the wsldevicehost `;swiotlb=` tokens
from PR #40518, mis-configuring DMA. Detect kernel support at runtime in
mini_init via env-var presence (unrecognized key=value cmdline params are
passed to init as env vars; early_param/__setup consumes them when the
patch is present). Report the bit back through LX_INIT_GUEST_CAPABILITIES
and cache the effective swiotlb value on WslCoreVm right after
ReadGuestCapabilities so both consumer sites (drvfs virtiofs and
VirtioProxy networking) reuse it and the kernel-unsupported warning fires
at most once. Move drvfs thread spawn after ReadGuestCapabilities so the
flag is available without a wait/event dance.

Enable swiotlb unconditionally on WSLC since it ships its own patched
kernel. Hoist c_swiotlbDefault to GuestDeviceManager.h and fold the
swiotlb=force hv_pci_swiotlb=<cfg> append into AppendCommonKernelCommandLine.

Replace the ad-hoc EnableVirtioFs/VirtioProxy consumer detection with the
EnableVirtio master switch, which also covers WSLg's virtio-fs device.
Reject NetworkingMode=VirtioProxy when EnableVirtio=false with a fallback
to NAT and a user warning.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 18, 2026 21:05
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

Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.

Comment thread src/windows/service/exe/WslCoreVm.cpp Outdated
@benhillis benhillis force-pushed the user/askariv/swiotlb-enable branch from 643d5f7 to 31ef8c1 Compare May 19, 2026 01:45
Copilot AI review requested due to automatic review settings May 19, 2026 22:27
@benhillis benhillis force-pushed the user/askariv/swiotlb-enable branch from 31ef8c1 to 0468b35 Compare May 19, 2026 22:27
@benhillis benhillis force-pushed the user/askariv/swiotlb-enable branch from 146ca92 to 5664a8f Compare May 20, 2026 19:01
@benhillis benhillis changed the title wslservice: Add experimental.swiotlb .wslconfig setting wslservice: Add swiotlb support with gating, vmId plumbing, and devicehost override May 20, 2026
Comment thread src/windows/common/helpers.cpp
@benhillis benhillis force-pushed the user/askariv/swiotlb-enable branch 5 times, most recently from b273696 to 6468f4e Compare May 22, 2026 19:58
@benhillis benhillis changed the title wslservice: Add swiotlb support with gating, vmId plumbing, and devicehost override wslservice: Improve VirtioFs performance with swiotlb, vmId plumbing, and devicehost override May 22, 2026
@benhillis benhillis changed the title wslservice: Improve VirtioFs performance with swiotlb, vmId plumbing, and devicehost override Improve VirtioFs performance with swiotlb May 22, 2026
@benhillis benhillis marked this pull request as ready for review May 22, 2026 20:00
@benhillis benhillis requested a review from a team as a code owner May 22, 2026 20:00
@benhillis benhillis force-pushed the user/askariv/swiotlb-enable branch from 6468f4e to 77a20c1 Compare May 22, 2026 20:03
Ben Hillis and others added 3 commits May 26, 2026 10:28
- Add experimental.swiotlb .wslconfig setting for custom bounce buffer
  configuration
- Gate swiotlb default computation: only compute when VirtioFs, Virtio9p,
  or VirtioProxy networking is enabled (both WSL2 and WSLC paths)
- Move virtio9p deprecation before swiotlb computation so disabled devices
  don't trigger unnecessary bounce buffer config
- Inject vmId=<machineId> into all virtio device options via
  GuestDeviceManager::AddHdvShareWithOptions for device-to-VM association
- Add WSL_DEVICE_HOST_DLL CMake override to replace wsldevicehost.dll
  without a NuGet update (dev-loop improvement)
- Fix empty-options guard to prevent double semicolons
- Add KernelSupportsHvPciSwiotlb to guest capabilities
- Add localization strings and validation for swiotlb config
- Update packages.config

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use a 1 GiB base for the default hv_pci_swiotlb reservation and require enough guest memory for the full reserved range before enabling it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@benhillis benhillis force-pushed the user/askariv/swiotlb-enable branch from 5555239 to ebd7a34 Compare May 26, 2026 17:29
<comment>{FixedPlaceholder="{}"}Command line arguments, file names and string inserts should not be translated</comment>
</data>
<data name="MessageConfigInvalidSwiotlb" xml:space="preserve">
<value>Invalid SWIOTLB value '{}' for key '{}' in {}:{}. Expected format: '0x&lt;hex&gt;,&lt;size&gt;K|M'</value>
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.

nit: Looks like your regex for the format allows for case-insensitive k|m as well. It lists only the uppercase as the expected format in other places in the code as well

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Correct, the example uses the more common use of K,M, but we still do allow a lowercase postfix.

// Reserve a swiotlb bounce buffer for virtio devices.
if (!swiotlbConfig.empty())
{
kernelCmdLine += std::format(L" swiotlb=force hv_pci_swiotlb={}", swiotlbConfig);
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.

Don't you need a sizing parameter for swiotlb (especially) along with 'force'? Without the sizing parameter, I am reading that it will default to 64MB floor on x86_64 systems (a bit better on arm where it tries to cap the automatic allocation at a maximum of 6% of total system RAM or a hard ceiling). I do feel that's low and will cause you to run out of swiotlb memory...

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

For this feature, we are using the kernel "swiotlb engine", and providing our own swiotlb pool, which the kernel uses for hv_pci devices. The hv_pci swiotlb pool parameters are specified via hv_pci_swiotlb=,.
Thus, we can leave the swiotlb default region to use the default size.


// Receive and parse the guest kernel version
ReadGuestCapabilities();

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.

Moving this before drvfs initialization would affect our startup latency? Before, the drvfs initialization could have proceeded concurrently with the kernel boot


// 1 GiB base sits below 4 GiB (32-bit PCI BAR limit on ARM64 virtio), below the Hyper-V
// low PCI MMIO hole (starts at >= 3 GiB on both x64 and ARM64), and above early boot allocations.
return L"0x40000000,64M";
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.

why do we return a hardcoded string here instead of using the c_swiotlbBase and c_swiotlbSize constants to construct it?

{
try
{
wil::com_ptr<IPlan9FileSystem> instance;
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.

Hmm, is this a fix for an existing issue? or needed for swiotlb buffer release or something?


MESSAGE_HEADER Header;
bool SeccompAvailable;
bool KernelSupportsHvPciSwiotlb;
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.

thinking out loud here. We shouldn't have to worry about backward compat when adding to this struct, because init and service will always be deployed together...?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This is for the case where the user uses a private kernel, that may or may not have the path.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Yes wslservice and init always come from the same build so this isn't an issue

@benhillis benhillis force-pushed the user/askariv/swiotlb-enable branch from 18acc78 to ebd7a34 Compare May 27, 2026 00:34
ConfigKey(ConfigSetting::Experimental::HostAddressLoopback, EnableHostAddressLoopback),
ConfigKey(ConfigSetting::Experimental::SetVersionDebug, SetVersionDebug)};
ConfigKey(ConfigSetting::Experimental::SetVersionDebug, SetVersionDebug),
ConfigKey(ConfigSetting::Experimental::Swiotlb, std::move(parseSwiotlb))};
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What's the thinking for exposing a new .wslconfig value for this ? Could we set a hardcoded value first ? That would greatly simplify this change

@asherkariv asherkariv closed this May 27, 2026
@asherkariv
Copy link
Copy Markdown
Author

Canceling this PR, as we have an updated PR using a different kernel patch, which lets the wsldevicehost know where the swiotlb region has been allocated.
#40654

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.

5 participants