Improve VirtioFs performance with swiotlb#40518
Conversation
There was a problem hiding this comment.
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.swiotlbparsing/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. |
|
I might be confused but I thought we didn’t need this setting until we have the updated kernel? |
…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>
643d5f7 to
31ef8c1
Compare
31ef8c1 to
0468b35
Compare
146ca92 to
5664a8f
Compare
b273696 to
6468f4e
Compare
6468f4e to
77a20c1
Compare
- 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>
5555239 to
ebd7a34
Compare
| <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<hex>,<size>K|M'</value> |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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...
There was a problem hiding this comment.
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(); | ||
|
|
There was a problem hiding this comment.
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"; |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
Hmm, is this a fix for an existing issue? or needed for swiotlb buffer release or something?
|
|
||
| MESSAGE_HEADER Header; | ||
| bool SeccompAvailable; | ||
| bool KernelSupportsHvPciSwiotlb; |
There was a problem hiding this comment.
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...?
There was a problem hiding this comment.
This is for the case where the user uses a private kernel, that may or may not have the path.
There was a problem hiding this comment.
Yes wslservice and init always come from the same build so this isn't an issue
18acc78 to
ebd7a34
Compare
| ConfigKey(ConfigSetting::Experimental::HostAddressLoopback, EnableHostAddressLoopback), | ||
| ConfigKey(ConfigSetting::Experimental::SetVersionDebug, SetVersionDebug)}; | ||
| ConfigKey(ConfigSetting::Experimental::SetVersionDebug, SetVersionDebug), | ||
| ConfigKey(ConfigSetting::Experimental::Swiotlb, std::move(parseSwiotlb))}; |
There was a problem hiding this comment.
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
|
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. |
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
Detailed Description
Commit 1: Add experimental.swiotlb .wslconfig setting
[experimental]config keyswiotlbto specify custom swiotlb configurationCommit 2: Swiotlb gating, vmId plumbing, and devicehost override
Validation Steps