mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-29 12:14:48 +00:00
clh,qemu: Adapt to using default_maxmemory
Let's adapt Cloud Hypervisor's and QEMU's code to properly behave to the newly added `default_maxmemory` config. While implementing this, a change of behaviour (or a bug fix, depending on how you see it) has been introduced as if a pod requests more memory than the amount avaiable in the host, instead of failing to start the pod, we simply hotplug the maximum amount of memory available, mimicing better the runc behaviour. Fixes: #4516 Signed-off-by: Fabiano Fidêncio <fabiano.fidencio@intel.com>
This commit is contained in:
parent
afdc960424
commit
58ff2bd5c9
@ -480,12 +480,9 @@ func (clh *cloudHypervisor) CreateVM(ctx context.Context, id string, network Net
|
|||||||
// Enable hugepages if needed
|
// Enable hugepages if needed
|
||||||
clh.vmconfig.Memory.Hugepages = func(b bool) *bool { return &b }(clh.config.HugePages)
|
clh.vmconfig.Memory.Hugepages = func(b bool) *bool { return &b }(clh.config.HugePages)
|
||||||
if !clh.config.ConfidentialGuest {
|
if !clh.config.ConfidentialGuest {
|
||||||
hostMemKb, err := GetHostMemorySizeKb(procMemInfo)
|
hotplugSize := clh.config.DefaultMaxMemorySize
|
||||||
if err != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// OpenAPI only supports int64 values
|
// OpenAPI only supports int64 values
|
||||||
clh.vmconfig.Memory.HotplugSize = func(i int64) *int64 { return &i }(int64((utils.MemUnit(hostMemKb) * utils.KiB).ToBytes()))
|
clh.vmconfig.Memory.HotplugSize = func(i int64) *int64 { return &i }(int64((utils.MemUnit(hotplugSize) * utils.MiB).ToBytes()))
|
||||||
}
|
}
|
||||||
// Set initial amount of cpu's for the virtual machine
|
// Set initial amount of cpu's for the virtual machine
|
||||||
clh.vmconfig.Cpus = chclient.NewCpusConfig(int32(clh.config.NumVCPUs), int32(clh.config.DefaultMaxVCPUs))
|
clh.vmconfig.Cpus = chclient.NewCpusConfig(int32(clh.config.NumVCPUs), int32(clh.config.DefaultMaxVCPUs))
|
||||||
@ -882,6 +879,11 @@ func (clh *cloudHypervisor) ResizeMemory(ctx context.Context, reqMemMB uint32, m
|
|||||||
return 0, MemoryDevice{}, err
|
return 0, MemoryDevice{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
maxHotplugSize := utils.MemUnit(*info.Config.Memory.HotplugSize) * utils.Byte
|
||||||
|
if reqMemMB > uint32(maxHotplugSize.ToMiB()) {
|
||||||
|
reqMemMB = uint32(maxHotplugSize.ToMiB())
|
||||||
|
}
|
||||||
|
|
||||||
currentMem := utils.MemUnit(info.Config.Memory.Size) * utils.Byte
|
currentMem := utils.MemUnit(info.Config.Memory.Size) * utils.Byte
|
||||||
newMem := utils.MemUnit(reqMemMB) * utils.MiB
|
newMem := utils.MemUnit(reqMemMB) * utils.MiB
|
||||||
|
|
||||||
|
@ -315,11 +315,7 @@ func (q *qemu) hostMemMB() (uint64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) memoryTopology() (govmmQemu.Memory, error) {
|
func (q *qemu) memoryTopology() (govmmQemu.Memory, error) {
|
||||||
hostMemMb, err := q.hostMemMB()
|
hostMemMb := q.config.DefaultMaxMemorySize
|
||||||
if err != nil {
|
|
||||||
return govmmQemu.Memory{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
memMb := uint64(q.config.MemorySize)
|
memMb := uint64(q.config.MemorySize)
|
||||||
|
|
||||||
return q.arch.memoryTopology(memMb, hostMemMb, uint8(q.config.MemSlots)), nil
|
return q.arch.memoryTopology(memMb, hostMemMb, uint8(q.config.MemSlots)), nil
|
||||||
@ -779,12 +775,8 @@ func (q *qemu) getMemArgs() (bool, string, string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (q *qemu) setupVirtioMem(ctx context.Context) error {
|
func (q *qemu) setupVirtioMem(ctx context.Context) error {
|
||||||
maxMem, err := q.hostMemMB()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// backend memory size must be multiple of 4Mib
|
// backend memory size must be multiple of 4Mib
|
||||||
sizeMB := (int(maxMem) - int(q.config.MemorySize)) >> 2 << 2
|
sizeMB := (int(q.config.DefaultMaxMemorySize) - int(q.config.MemorySize)) >> 2 << 2
|
||||||
|
|
||||||
share, target, memoryBack, err := q.getMemArgs()
|
share, target, memoryBack, err := q.getMemArgs()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1970,8 +1962,6 @@ func (q *qemu) hotplugMemory(memDev *MemoryDevice, op Operation) (int, error) {
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
currentMemory := int(q.config.MemorySize) + q.state.HotpluggedMemory
|
|
||||||
|
|
||||||
if memDev.SizeMB == 0 {
|
if memDev.SizeMB == 0 {
|
||||||
memLog.Debug("hotplug is not required")
|
memLog.Debug("hotplug is not required")
|
||||||
return 0, nil
|
return 0, nil
|
||||||
@ -1985,17 +1975,7 @@ func (q *qemu) hotplugMemory(memDev *MemoryDevice, op Operation) (int, error) {
|
|||||||
return 0, nil
|
return 0, nil
|
||||||
case AddDevice:
|
case AddDevice:
|
||||||
memLog.WithField("operation", "add").Debugf("Requested to add memory: %d MB", memDev.SizeMB)
|
memLog.WithField("operation", "add").Debugf("Requested to add memory: %d MB", memDev.SizeMB)
|
||||||
maxMem, err := q.hostMemMB()
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't exceed the maximum amount of memory
|
|
||||||
if currentMemory+memDev.SizeMB > int(maxMem) {
|
|
||||||
// Fixme: return a typed error
|
|
||||||
return 0, fmt.Errorf("Unable to hotplug %d MiB memory, the SB has %d MiB and the maximum amount is %d MiB",
|
|
||||||
memDev.SizeMB, currentMemory, maxMem)
|
|
||||||
}
|
|
||||||
memoryAdded, err := q.hotplugAddMemory(memDev)
|
memoryAdded, err := q.hotplugAddMemory(memDev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return memoryAdded, err
|
return memoryAdded, err
|
||||||
@ -2231,6 +2211,11 @@ func (q *qemu) ResizeMemory(ctx context.Context, reqMemMB uint32, memoryBlockSiz
|
|||||||
case currentMemory < reqMemMB:
|
case currentMemory < reqMemMB:
|
||||||
//hotplug
|
//hotplug
|
||||||
addMemMB := reqMemMB - currentMemory
|
addMemMB := reqMemMB - currentMemory
|
||||||
|
|
||||||
|
if currentMemory+addMemMB > uint32(q.config.DefaultMaxMemorySize) {
|
||||||
|
addMemMB = uint32(q.config.DefaultMaxMemorySize) - currentMemory
|
||||||
|
}
|
||||||
|
|
||||||
memHotplugMB, err := calcHotplugMemMiBSize(addMemMB, memoryBlockSizeMB)
|
memHotplugMB, err := calcHotplugMemMiBSize(addMemMB, memoryBlockSizeMB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return currentMemory, MemoryDevice{}, err
|
return currentMemory, MemoryDevice{}, err
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/persist"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types"
|
||||||
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
"github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils"
|
||||||
|
"github.com/pbnjay/memory"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@ -172,6 +173,7 @@ func TestQemuCPUTopology(t *testing.T) {
|
|||||||
|
|
||||||
func TestQemuMemoryTopology(t *testing.T) {
|
func TestQemuMemoryTopology(t *testing.T) {
|
||||||
mem := uint32(1000)
|
mem := uint32(1000)
|
||||||
|
maxMem := memory.TotalMemory() / 1024 / 1024 //MiB
|
||||||
slots := uint32(8)
|
slots := uint32(8)
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
@ -180,12 +182,11 @@ func TestQemuMemoryTopology(t *testing.T) {
|
|||||||
config: HypervisorConfig{
|
config: HypervisorConfig{
|
||||||
MemorySize: mem,
|
MemorySize: mem,
|
||||||
MemSlots: slots,
|
MemSlots: slots,
|
||||||
|
DefaultMaxMemorySize: maxMem,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
hostMemKb, err := GetHostMemorySizeKb(procMemInfo)
|
memMax := fmt.Sprintf("%dM", int(maxMem))
|
||||||
assert.NoError(err)
|
|
||||||
memMax := fmt.Sprintf("%dM", int(float64(hostMemKb)/1024))
|
|
||||||
|
|
||||||
expectedOut := govmmQemu.Memory{
|
expectedOut := govmmQemu.Memory{
|
||||||
Size: fmt.Sprintf("%dM", mem),
|
Size: fmt.Sprintf("%dM", mem),
|
||||||
|
Loading…
Reference in New Issue
Block a user