Repository navigation
Conversation
Attach a VZVirtioTraditionalMemoryBalloonDeviceConfiguration to every VZVirtualMachineConfiguration built by VZVirtualMachineInstance. The device is inert until the host lowers its targetVirtualMachineMemorySize, which starts at the configured memory size, so existing VMs behave the same. A guest kernel without the virtio-balloon driver ignores it; the repo's arm64 and x86_64 kernels build it in. This only makes the device available. A follow-up adds an API to set the target size. Also add docs/memory-balloon.md describing the design: balloon semantics, how Virtualization.framework exposes it, and why the target is a request rather than a guarantee. VZ requires the configuration to match when restoring saved machine state, so state saved before this change will not restore.
Expose the virtio memory balloon's target memory size so callers can ask a running guest to give memory back to the host, or take it back. It is reached through withVirtualMachineInstance rather than LinuxContainer or LinuxPod, since it is a low-level VMM operation. The method requires a running VM and validates the size instead of relying on Virtualization.framework, which silently rounds and clamps: the size must be a multiple of 1 MiB, at least VZVirtualMachineConfiguration.minimumAllowedMemorySize, and at most the configured memory. It throws if the VM has no balloon device. The target is a request; the guest may honor it partly or never, and the actual balloon size cannot be read back. The configured memory rounding is factored into Configuration.vzMemorySize so toVZ and the validation share it. Add unit tests for the range checks and the rounding.
Boot a VM, check that the guest bound a driver to the default balloon device, and fill the page cache with a 128 MB file so the container's memory usage rises. Then lower the balloon's target memory size to an eighth of the VM's memory and check, through container.statistics, that usage falls below 3/4 of its earlier value as the guest reclaims the cache to feed the balloon. Without the balloon call, usage stays flat. Also check that setTargetVirtualMachineMemory(size:) rejects a size above the configured memory, a size that is not a multiple of 1 MiB, and zero. The test is macOS-only, as the balloon is a VZ feature.
|
Host-side measurement of this PR on macOS 26.6.2 I built this branch ( Setup: Apple M5 Max, macOS 26.6.2 (Xcode 27.2, Swift 6.4.2).
A second run compared Result: the guest side works as the PR describes. The driver inflates and deflates within seconds. On macOS 26.6.2, though, the inflate does not lower the VM process's footprint, RSS, or dirty memory. This agrees with the note in #65 that ballooning only partially works on macOS. I did not test whether macOS reclaims ballooned pages faster under host memory pressure. Two small notes:
|
|
Yeah. Seems we have some issue in the host side VM memory management. Will figure out! |
Attach a virtio memory balloon device to every VZVirtualMachineInstance and add setTargetVirtualMachineMemory(size:) so a host can ask a running guest to give memory back, or take it back.