mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-08-30 23:37:45 +00:00
runtime: qemu: Add reclaim_guest_freed_memory [BACKPORT]
Similar to what we've done for Cloud Hypervisor in the commit
9f76467cb7
, we're backporting a runtime-rs
feature that would be benificial to have as part of the go runtime.
This allows users to use virito-balloon for the hypervisor to reclaim
memory freed by the guest.
Signed-off-by: Fabiano Fidêncio <fidencio@northflank.com>
This commit is contained in:
parent
e396a460bc
commit
fd1b8ceed1
@ -273,6 +273,16 @@ enable_iothreads = @DEFENABLEIOTHREADS@
|
||||
# Default false
|
||||
#enable_mem_prealloc = true
|
||||
|
||||
# Reclaim guest freed memory.
|
||||
# Enabling this will result in the VM balloon device having f_reporting=on set.
|
||||
# Then the hypervisor will use it to reclaim guest freed memory.
|
||||
# This is useful for reducing the amount of memory used by a VM.
|
||||
# Enabling this feature may sometimes reduce the speed of memory access in
|
||||
# the VM.
|
||||
#
|
||||
# Default false
|
||||
#reclaim_guest_freed_memory = true
|
||||
|
||||
# Enable huge pages for VM RAM, default false
|
||||
# Enabling this will result in the VM memory
|
||||
# being allocated using huge pages.
|
||||
|
@ -290,6 +290,16 @@ enable_iothreads = @DEFENABLEIOTHREADS@
|
||||
# Default false
|
||||
#enable_mem_prealloc = true
|
||||
|
||||
# Reclaim guest freed memory.
|
||||
# Enabling this will result in the VM balloon device having f_reporting=on set.
|
||||
# Then the hypervisor will use it to reclaim guest freed memory.
|
||||
# This is useful for reducing the amount of memory used by a VM.
|
||||
# Enabling this feature may sometimes reduce the speed of memory access in
|
||||
# the VM.
|
||||
#
|
||||
# Default false
|
||||
#reclaim_guest_freed_memory = true
|
||||
|
||||
# Enable huge pages for VM RAM, default false
|
||||
# Enabling this will result in the VM memory
|
||||
# being allocated using huge pages.
|
||||
|
@ -266,6 +266,16 @@ enable_iothreads = @DEFENABLEIOTHREADS@
|
||||
# Default false
|
||||
#enable_mem_prealloc = true
|
||||
|
||||
# Reclaim guest freed memory.
|
||||
# Enabling this will result in the VM balloon device having f_reporting=on set.
|
||||
# Then the hypervisor will use it to reclaim guest freed memory.
|
||||
# This is useful for reducing the amount of memory used by a VM.
|
||||
# Enabling this feature may sometimes reduce the speed of memory access in
|
||||
# the VM.
|
||||
#
|
||||
# Default false
|
||||
#reclaim_guest_freed_memory = true
|
||||
|
||||
# Enable huge pages for VM RAM, default false
|
||||
# Enabling this will result in the VM memory
|
||||
# being allocated using huge pages.
|
||||
|
@ -271,6 +271,16 @@ enable_iothreads = @DEFENABLEIOTHREADS@
|
||||
# Default false
|
||||
#enable_mem_prealloc = true
|
||||
|
||||
# Reclaim guest freed memory.
|
||||
# Enabling this will result in the VM balloon device having f_reporting=on set.
|
||||
# Then the hypervisor will use it to reclaim guest freed memory.
|
||||
# This is useful for reducing the amount of memory used by a VM.
|
||||
# Enabling this feature may sometimes reduce the speed of memory access in
|
||||
# the VM.
|
||||
#
|
||||
# Default false
|
||||
#reclaim_guest_freed_memory = true
|
||||
|
||||
# Enable huge pages for VM RAM, default false
|
||||
# Enabling this will result in the VM memory
|
||||
# being allocated using huge pages.
|
||||
|
@ -257,6 +257,16 @@ enable_iothreads = @DEFENABLEIOTHREADS@
|
||||
# Default false
|
||||
#enable_mem_prealloc = true
|
||||
|
||||
# Reclaim guest freed memory.
|
||||
# Enabling this will result in the VM balloon device having f_reporting=on set.
|
||||
# Then the hypervisor will use it to reclaim guest freed memory.
|
||||
# This is useful for reducing the amount of memory used by a VM.
|
||||
# Enabling this feature may sometimes reduce the speed of memory access in
|
||||
# the VM.
|
||||
#
|
||||
# Default false
|
||||
#reclaim_guest_freed_memory = true
|
||||
|
||||
# Enable huge pages for VM RAM, default false
|
||||
# Enabling this will result in the VM memory
|
||||
# being allocated using huge pages.
|
||||
|
@ -290,6 +290,16 @@ enable_iothreads = @DEFENABLEIOTHREADS@
|
||||
# Default false
|
||||
#enable_mem_prealloc = true
|
||||
|
||||
# Reclaim guest freed memory.
|
||||
# Enabling this will result in the VM balloon device having f_reporting=on set.
|
||||
# Then the hypervisor will use it to reclaim guest freed memory.
|
||||
# This is useful for reducing the amount of memory used by a VM.
|
||||
# Enabling this feature may sometimes reduce the speed of memory access in
|
||||
# the VM.
|
||||
#
|
||||
# Default false
|
||||
#reclaim_guest_freed_memory = true
|
||||
|
||||
# Enable huge pages for VM RAM, default false
|
||||
# Enabling this will result in the VM memory
|
||||
# being allocated using huge pages.
|
||||
|
@ -267,6 +267,16 @@ enable_iothreads = @DEFENABLEIOTHREADS@
|
||||
# Default false
|
||||
#enable_mem_prealloc = true
|
||||
|
||||
# Reclaim guest freed memory.
|
||||
# Enabling this will result in the VM balloon device having f_reporting=on set.
|
||||
# Then the hypervisor will use it to reclaim guest freed memory.
|
||||
# This is useful for reducing the amount of memory used by a VM.
|
||||
# Enabling this feature may sometimes reduce the speed of memory access in
|
||||
# the VM.
|
||||
#
|
||||
# Default false
|
||||
#reclaim_guest_freed_memory = true
|
||||
|
||||
# Enable huge pages for VM RAM, default false
|
||||
# Enabling this will result in the VM memory
|
||||
# being allocated using huge pages.
|
||||
|
@ -272,6 +272,16 @@ enable_iothreads = @DEFENABLEIOTHREADS@
|
||||
# Default false
|
||||
#enable_mem_prealloc = true
|
||||
|
||||
# Reclaim guest freed memory.
|
||||
# Enabling this will result in the VM balloon device having f_reporting=on set.
|
||||
# Then the hypervisor will use it to reclaim guest freed memory.
|
||||
# This is useful for reducing the amount of memory used by a VM.
|
||||
# Enabling this feature may sometimes reduce the speed of memory access in
|
||||
# the VM.
|
||||
#
|
||||
# Default false
|
||||
#reclaim_guest_freed_memory = true
|
||||
|
||||
# Enable huge pages for VM RAM, default false
|
||||
# Enabling this will result in the VM memory
|
||||
# being allocated using huge pages.
|
||||
|
@ -439,6 +439,14 @@ type RNGDev struct {
|
||||
Filename string
|
||||
}
|
||||
|
||||
// BalloonDev represents a balloon device
|
||||
type BalloonDev struct {
|
||||
ID string
|
||||
DeflateOnOOM bool
|
||||
DisableModern bool
|
||||
FreePageReporting bool
|
||||
}
|
||||
|
||||
// VhostUserDeviceAttrs represents data shared by most vhost-user devices
|
||||
type VhostUserDeviceAttrs struct {
|
||||
DevID string
|
||||
|
@ -2409,9 +2409,10 @@ func (v RngDevice) deviceName(config *Config) string {
|
||||
// BalloonDevice represents a memory balloon device.
|
||||
// nolint: govet
|
||||
type BalloonDevice struct {
|
||||
DeflateOnOOM bool
|
||||
DisableModern bool
|
||||
ID string
|
||||
DeflateOnOOM bool
|
||||
DisableModern bool
|
||||
FreePageReporting bool
|
||||
ID string
|
||||
|
||||
// ROMFile specifies the ROM file being used for this device.
|
||||
ROMFile string
|
||||
@ -2458,6 +2459,11 @@ func (b BalloonDevice) QemuParams(config *Config) []string {
|
||||
if s := b.Transport.disableModern(config, b.DisableModern); s != "" {
|
||||
deviceParams = append(deviceParams, s)
|
||||
}
|
||||
if b.FreePageReporting {
|
||||
deviceParams = append(deviceParams, "free-page-reporting=on")
|
||||
} else {
|
||||
deviceParams = append(deviceParams, "free-page-reporting=off")
|
||||
}
|
||||
qemuParams = append(qemuParams, "-device")
|
||||
qemuParams = append(qemuParams, strings.Join(deviceParams, ","))
|
||||
|
||||
|
@ -80,14 +80,19 @@ func TestAppendVirtioBalloon(t *testing.T) {
|
||||
var OnDisableModern = ",disable-modern=true"
|
||||
var OffDisableModern = ",disable-modern=false"
|
||||
|
||||
testAppend(balloonDevice, deviceString+OffDeflateOnOMM+OffDisableModern, t)
|
||||
var OnFreePageReporting = ",free-page-reporting=on"
|
||||
var OffFreePageReporting = ",free-page-reporting=off"
|
||||
|
||||
testAppend(balloonDevice, deviceString+OffDeflateOnOMM+OffDisableModern+OffFreePageReporting, t)
|
||||
|
||||
balloonDevice.DeflateOnOOM = true
|
||||
testAppend(balloonDevice, deviceString+OnDeflateOnOMM+OffDisableModern, t)
|
||||
testAppend(balloonDevice, deviceString+OnDeflateOnOMM+OffDisableModern+OffFreePageReporting, t)
|
||||
|
||||
balloonDevice.DisableModern = true
|
||||
testAppend(balloonDevice, deviceString+OnDeflateOnOMM+OnDisableModern, t)
|
||||
testAppend(balloonDevice, deviceString+OnDeflateOnOMM+OnDisableModern+OffFreePageReporting, t)
|
||||
|
||||
balloonDevice.FreePageReporting = true
|
||||
testAppend(balloonDevice, deviceString+OnDeflateOnOMM+OnDisableModern+OnFreePageReporting, t)
|
||||
}
|
||||
|
||||
func TestAppendPCIBridgeDevice(t *testing.T) {
|
||||
|
@ -35,10 +35,17 @@ func TestAppendVirtioBalloon(t *testing.T) {
|
||||
|
||||
var OnDeflateOnOMM = ",deflate-on-oom=on"
|
||||
var OffDeflateOnOMM = ",deflate-on-oom=off"
|
||||
testAppend(balloonDevice, deviceString+devnoOptios+OffDeflateOnOMM, t)
|
||||
|
||||
var OnFreePageReporting = ",free-page-reporting=on"
|
||||
var OffFreePageReporting = ",free-page-reporting=off"
|
||||
|
||||
testAppend(balloonDevice, deviceString+devnoOptios+OffDeflateOnOMM+OffFreePageReporting, t)
|
||||
|
||||
balloonDevice.DeflateOnOOM = true
|
||||
testAppend(balloonDevice, deviceString+devnoOptios+OnDeflateOnOMM, t)
|
||||
testAppend(balloonDevice, deviceString+devnoOptios+OnDeflateOnOMM+OffFreePageReporting, t)
|
||||
|
||||
balloonDevice.FreePageReporting = true
|
||||
testAppend(balloonDevice, deviceString+devnoOptios+OnDeflateOnOMM+OnFreePageReporting, t)
|
||||
}
|
||||
|
||||
func TestAppendDeviceFSCCW(t *testing.T) {
|
||||
|
@ -952,6 +952,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
|
||||
VirtioFSQueueSize: h.VirtioFSQueueSize,
|
||||
VirtioFSExtraArgs: h.VirtioFSExtraArgs,
|
||||
MemPrealloc: h.MemPrealloc,
|
||||
ReclaimGuestFreedMemory: h.ReclaimGuestFreedMemory,
|
||||
HugePages: h.HugePages,
|
||||
IOMMU: h.IOMMU,
|
||||
IOMMUPlatform: h.getIOMMUPlatform(),
|
||||
|
@ -139,6 +139,7 @@ const (
|
||||
scsiControllerID = "scsi0"
|
||||
rngID = "rng0"
|
||||
fallbackFileBackedMemDir = "/dev/shm"
|
||||
balloonID = "balloon0"
|
||||
|
||||
qemuStopSandboxTimeoutSecs = 15
|
||||
|
||||
@ -632,6 +633,9 @@ func (q *qemu) prepareInitdataMount(config *HypervisorConfig) error {
|
||||
}
|
||||
|
||||
// CreateVM is the Hypervisor VM creation implementation for govmmQemu.
|
||||
// This function is complex and there's not much to be done about it, unfortunately.
|
||||
//
|
||||
//nolint:gocyclo
|
||||
func (q *qemu) CreateVM(ctx context.Context, id string, network Network, hypervisorConfig *HypervisorConfig) error {
|
||||
// Save the tracing context
|
||||
q.ctx = ctx
|
||||
@ -801,6 +805,20 @@ func (q *qemu) CreateVM(ctx context.Context, id string, network Network, hypervi
|
||||
}
|
||||
}
|
||||
|
||||
if q.config.ReclaimGuestFreedMemory && !q.config.ConfidentialGuest {
|
||||
balloonDev := config.BalloonDev{
|
||||
ID: balloonID,
|
||||
DeflateOnOOM: true,
|
||||
DisableModern: false,
|
||||
FreePageReporting: true,
|
||||
}
|
||||
|
||||
qemuConfig.Devices, err = q.arch.appendBalloonDevice(ctx, qemuConfig.Devices, balloonDev)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if machine.Type == QemuQ35 || machine.Type == QemuVirt {
|
||||
if err := q.createPCIeTopology(&qemuConfig, hypervisorConfig, machine.Type, network); err != nil {
|
||||
q.Logger().WithError(err).Errorf("Cannot create PCIe topology")
|
||||
|
@ -116,6 +116,9 @@ type qemuArch interface {
|
||||
// appendRNGDevice appends a RNG device to devices
|
||||
appendRNGDevice(ctx context.Context, devices []govmmQemu.Device, rngDevice config.RNGDev) ([]govmmQemu.Device, error)
|
||||
|
||||
// appendBalloonDevice appends a Balloon device to devices
|
||||
appendBalloonDevice(ctx context.Context, devices []govmmQemu.Device, BalloonDevice config.BalloonDev) ([]govmmQemu.Device, error)
|
||||
|
||||
// setEndpointDevicePath sets the appropriate PCI or CCW device path for an endpoint
|
||||
setEndpointDevicePath(endpoint Endpoint, bridgeAddr int, devAddr string) error
|
||||
|
||||
@ -738,6 +741,19 @@ func (q *qemuArchBase) appendRNGDevice(_ context.Context, devices []govmmQemu.De
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func (q *qemuArchBase) appendBalloonDevice(_ context.Context, devices []govmmQemu.Device, balloonDev config.BalloonDev) ([]govmmQemu.Device, error) {
|
||||
devices = append(devices,
|
||||
govmmQemu.BalloonDevice{
|
||||
ID: balloonDev.ID,
|
||||
DeflateOnOOM: balloonDev.DeflateOnOOM,
|
||||
DisableModern: balloonDev.DisableModern,
|
||||
FreePageReporting: balloonDev.FreePageReporting,
|
||||
},
|
||||
)
|
||||
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func (q *qemuArchBase) setEndpointDevicePath(endpoint Endpoint, bridgeAddr int, devAddr string) error {
|
||||
bridgeSlot, err := types.PciSlotFromInt(bridgeAddr)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user