Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
config: Add Memory slots configuration.
Browse files Browse the repository at this point in the history
Add configuration to decide the amount of slots that will be used in a VM

- This will limit the amount of times that memory can be hotplugged.
- Use memory slots provided by user.
- tests: aling struct

cli: kata-env: Add memory slots info.

- Show the slots to be added to the VM.

```diff
[Hypervisor]
  MachineType = "pc"
  Version = "QEMU ..."
  Path = "/opt/kata/bin/qemu-system-x86_64"
  BlockDeviceDriver = "virtio-scsi"
  Msize9p = 8192
+  MemorySlots = 10
  Debug = false
  UseVSock = false
```

Fixes: #751

Signed-off-by: Jose Carlos Venegas Munoz <[email protected]>
  • Loading branch information
jcvenegas committed Sep 21, 2018
1 parent 76b0c3c commit 19801bf
Show file tree
Hide file tree
Showing 16 changed files with 82 additions and 44 deletions.
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ DEFVCPUS := 1
DEFMAXVCPUS := 0
# Default memory size in MiB
DEFMEMSZ := 2048
# Default memory slots
# Cases to consider :
# - nvdimm rootfs image
# - preallocated memory
# - vm template memory
# - hugepage memory
DEFMEMSLOTS := 10
#Default number of bridges
DEFBRIDGES := 1
#Default network model
Expand Down Expand Up @@ -202,6 +209,7 @@ USER_VARS += SYSCONFDIR
USER_VARS += DEFVCPUS
USER_VARS += DEFMAXVCPUS
USER_VARS += DEFMEMSZ
USER_VARS += DEFMEMSLOTS
USER_VARS += DEFBRIDGES
USER_VARS += DEFNETWORKMODEL
USER_VARS += DEFDISABLEBLOCK
Expand Down Expand Up @@ -302,6 +310,7 @@ const defaultRootDirectory = "$(PKGRUNDIR)"
const defaultVCPUCount uint32 = $(DEFVCPUS)
const defaultMaxVCPUCount uint32 = $(DEFMAXVCPUS)
const defaultMemSize uint32 = $(DEFMEMSZ) // MiB
const defaultMemSlots uint32 = $(DEFMEMSLOTS)
const defaultBridgesCount uint32 = $(DEFBRIDGES)
const defaultInterNetworkingModel = "$(DEFNETWORKMODEL)"
const defaultDisableBlockDeviceUse bool = $(DEFDISABLEBLOCK)
Expand Down Expand Up @@ -391,6 +400,7 @@ $(GENERATED_FILES): %: %.in Makefile VERSION
-e "s|@DEFVCPUS@|$(DEFVCPUS)|g" \
-e "s|@DEFMAXVCPUS@|$(DEFMAXVCPUS)|g" \
-e "s|@DEFMEMSZ@|$(DEFMEMSZ)|g" \
-e "s|@DEFMEMSLOTS@|$(DEFMEMSLOTS)|g" \
-e "s|@DEFBRIDGES@|$(DEFBRIDGES)|g" \
-e "s|@DEFNETWORKMODEL@|$(DEFNETWORKMODEL)|g" \
-e "s|@DEFDISABLEBLOCK@|$(DEFDISABLEBLOCK)|g" \
Expand Down
11 changes: 11 additions & 0 deletions cli/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type hypervisor struct {
NumVCPUs int32 `toml:"default_vcpus"`
DefaultMaxVCPUs uint32 `toml:"default_maxvcpus"`
MemorySize uint32 `toml:"default_memory"`
MemSlots uint32 `toml:"memory_slots"`
DefaultBridges uint32 `toml:"default_bridges"`
Msize9p uint32 `toml:"msize_9p"`
DisableBlockDeviceUse bool `toml:"disable_block_device_use"`
Expand Down Expand Up @@ -247,6 +248,15 @@ func (h hypervisor) defaultMemSz() uint32 {
return h.MemorySize
}

func (h hypervisor) defaultMemSlots() uint32 {
slots := h.MemSlots
if slots == 0 {
slots = defaultMemSlots
}

return slots
}

func (h hypervisor) defaultBridges() uint32 {
if h.DefaultBridges == 0 {
return defaultBridgesCount
Expand Down Expand Up @@ -392,6 +402,7 @@ func newQemuHypervisorConfig(h hypervisor) (vc.HypervisorConfig, error) {
NumVCPUs: h.defaultVCPUs(),
DefaultMaxVCPUs: h.defaultMaxVCPUs(),
MemorySize: h.defaultMemSz(),
MemSlots: h.defaultMemSlots(),
DefaultBridges: h.defaultBridges(),
DisableBlockDeviceUse: h.DisableBlockDeviceUse,
MemPrealloc: h.MemPrealloc,
Expand Down
5 changes: 5 additions & 0 deletions cli/config/configuration.toml.in
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ default_bridges = @DEFBRIDGES@
# Default memory size in MiB for SB/VM.
# If unspecified then it will be set @DEFMEMSZ@ MiB.
#default_memory = @DEFMEMSZ@
#
# Default memory slots per SB/VM.
# If unspecified then it will be set @DEFMEMSLOTS@.
# This is will determine the times that memory will be hotadded to sandbox/VM.
#memory_slots = @DEFMEMSLOTS@

# Disable block device from being used for a container's rootfs.
# In case of a storage driver like devicemapper where a container's
Expand Down
1 change: 1 addition & 0 deletions cli/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ func createAllRuntimeConfigFiles(dir, hypervisor string) (config testRuntimeConf
EnableIOThreads: enableIOThreads,
HotplugVFIOOnRootBus: hotplugVFIOOnRootBus,
Msize9p: defaultMsize9p,
MemSlots: defaultMemSlots,
}

agentConfig := vc.KataAgentConfig{}
Expand Down
4 changes: 3 additions & 1 deletion cli/kata-env.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
//
// XXX: Increment for every change to the output format
// (meaning any change to the EnvInfo type).
const formatVersion = "1.0.16"
const formatVersion = "1.0.17"

// MetaInfo stores information on the format of the output itself
type MetaInfo struct {
Expand Down Expand Up @@ -82,6 +82,7 @@ type HypervisorInfo struct {
Path string
BlockDeviceDriver string
Msize9p uint32
MemorySlots uint32
Debug bool
UseVSock bool
}
Expand Down Expand Up @@ -317,6 +318,7 @@ func getHypervisorInfo(config oci.RuntimeConfig) HypervisorInfo {
BlockDeviceDriver: config.HypervisorConfig.BlockDeviceDriver,
Msize9p: config.HypervisorConfig.Msize9p,
UseVSock: config.HypervisorConfig.UseVSock,
MemorySlots: config.HypervisorConfig.MemSlots,
}
}

Expand Down
1 change: 1 addition & 0 deletions cli/kata-env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ func getExpectedHypervisor(config oci.RuntimeConfig) HypervisorInfo {
MachineType: config.HypervisorConfig.HypervisorMachineType,
BlockDeviceDriver: config.HypervisorConfig.BlockDeviceDriver,
Msize9p: config.HypervisorConfig.Msize9p,
MemorySlots: config.HypervisorConfig.MemSlots,
Debug: config.HypervisorConfig.Debug,
}
}
Expand Down
51 changes: 27 additions & 24 deletions virtcontainers/hypervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,25 @@ type Param struct {

// HypervisorConfig is the hypervisor configuration.
type HypervisorConfig struct {
// NumVCPUs specifies default number of vCPUs for the VM.
NumVCPUs uint32

//DefaultMaxVCPUs specifies the maximum number of vCPUs for the VM.
DefaultMaxVCPUs uint32

// DefaultMem specifies default memory size in MiB for the VM.
MemorySize uint32

// DefaultBridges specifies default number of bridges for the VM.
// Bridges can be used to hot plug devices
DefaultBridges uint32

// Msize9p is used as the msize for 9p shares
Msize9p uint32

// MemSlots specifies default memory slots the VM.
MemSlots uint32

// KernelParams are additional guest kernel parameters.
KernelParams []Param

Expand Down Expand Up @@ -169,25 +188,20 @@ type HypervisorConfig struct {
// emulated.
HypervisorMachineType string

// MemoryPath is the memory file path of VM memory. Used when either BootToBeTemplate or
// BootFromTemplate is true.
MemoryPath string

// DevicesStatePath is the VM device state file path. Used when either BootToBeTemplate or
// BootFromTemplate is true.
DevicesStatePath string

// customAssets is a map of assets.
// Each value in that map takes precedence over the configured assets.
// For example, if there is a value for the "kernel" key in this map,
// it will be used for the sandbox's kernel path instead of KernelPath.
customAssets map[assetType]*asset

// NumVCPUs specifies default number of vCPUs for the VM.
NumVCPUs uint32

//DefaultMaxVCPUs specifies the maximum number of vCPUs for the VM.
DefaultMaxVCPUs uint32

// DefaultMem specifies default memory size in MiB for the VM.
MemorySize uint32

// DefaultBridges specifies default number of bridges for the VM.
// Bridges can be used to hot plug devices
DefaultBridges uint32

// DisableBlockDeviceUse disallows a block device from being used.
DisableBlockDeviceUse bool

Expand Down Expand Up @@ -217,9 +231,6 @@ type HypervisorConfig struct {
// when running on top of another VMM.
DisableNestingChecks bool

// Msize9p is used as the msize for 9p shares
Msize9p uint32

// UseVSock use a vsock for agent communication
UseVSock bool

Expand All @@ -233,14 +244,6 @@ type HypervisorConfig struct {
// BootFromTemplate used to indicate if the VM should be created from a template VM
BootFromTemplate bool

// MemoryPath is the memory file path of VM memory. Used when either BootToBeTemplate or
// BootFromTemplate is true.
MemoryPath string

// DevicesStatePath is the VM device state file path. Used when either BootToBeTemplate or
// BootFromTemplate is true.
DevicesStatePath string

// DisableVhostNet is used to indicate if host supports vhost_net
DisableVhostNet bool
}
Expand Down
6 changes: 3 additions & 3 deletions virtcontainers/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ func (q *qemu) memoryTopology() (govmmQemu.Memory, error) {

memMb := uint64(q.config.MemorySize)

return q.arch.memoryTopology(memMb, hostMemMb), nil
return q.arch.memoryTopology(memMb, hostMemMb, uint8(q.config.MemSlots)), nil
}

func (q *qemu) qmpSocketPath(id string) (string, error) {
Expand Down Expand Up @@ -1236,7 +1236,7 @@ func genericBridges(number uint32, machineType string) []Bridge {
return bridges
}

func genericMemoryTopology(memoryMb, hostMemoryMb uint64) govmmQemu.Memory {
func genericMemoryTopology(memoryMb, hostMemoryMb uint64, slots uint8) govmmQemu.Memory {
// NVDIMM device needs memory space 1024MB
// See https://github.com/clearcontainers/runtime/issues/380
memoryOffset := 1024
Expand All @@ -1248,7 +1248,7 @@ func genericMemoryTopology(memoryMb, hostMemoryMb uint64) govmmQemu.Memory {

memory := govmmQemu.Memory{
Size: mem,
Slots: defaultMemSlots,
Slots: slots,
MaxMem: memMax,
}

Expand Down
4 changes: 2 additions & 2 deletions virtcontainers/qemu_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ func (q *qemuAmd64) cpuModel() string {
return cpuModel
}

func (q *qemuAmd64) memoryTopology(memoryMb, hostMemoryMb uint64) govmmQemu.Memory {
return genericMemoryTopology(memoryMb, hostMemoryMb)
func (q *qemuAmd64) memoryTopology(memoryMb, hostMemoryMb uint64, slots uint8) govmmQemu.Memory {
return genericMemoryTopology(memoryMb, hostMemoryMb, slots)
}

func (q *qemuAmd64) appendImage(devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) {
Expand Down
5 changes: 3 additions & 2 deletions virtcontainers/qemu_amd64_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,14 @@ func TestQemuAmd64MemoryTopology(t *testing.T) {

hostMem := uint64(100)
mem := uint64(120)
slots := uint8(10)
expectedMemory := govmmQemu.Memory{
Size: fmt.Sprintf("%dM", mem),
Slots: defaultMemSlots,
Slots: slots,
MaxMem: fmt.Sprintf("%dM", hostMem+uint64(memoryOffset)),
}

m := amd64.memoryTopology(mem, hostMem)
m := amd64.memoryTopology(mem, hostMem, slots)
assert.Equal(expectedMemory, m)
}

Expand Down
7 changes: 3 additions & 4 deletions virtcontainers/qemu_arch_base.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type qemuArch interface {
cpuModel() string

// memoryTopology returns the memory topology using the given amount of memoryMb and hostMemoryMb
memoryTopology(memoryMb, hostMemoryMb uint64) govmmQemu.Memory
memoryTopology(memoryMb, hostMemoryMb uint64, slots uint8) govmmQemu.Memory

// appendConsole appends a console to devices
appendConsole(devices []govmmQemu.Device, path string) []govmmQemu.Device
Expand Down Expand Up @@ -110,7 +110,6 @@ type qemuArchBase struct {
const (
defaultCores uint32 = 1
defaultThreads uint32 = 1
defaultMemSlots uint8 = 2
defaultCPUModel = "host"
defaultBridgeBus = "pcie.0"
maxDevIDSize = 31
Expand Down Expand Up @@ -258,12 +257,12 @@ func (q *qemuArchBase) cpuModel() string {
return defaultCPUModel
}

func (q *qemuArchBase) memoryTopology(memoryMb, hostMemoryMb uint64) govmmQemu.Memory {
func (q *qemuArchBase) memoryTopology(memoryMb, hostMemoryMb uint64, slots uint8) govmmQemu.Memory {
memMax := fmt.Sprintf("%dM", hostMemoryMb)
mem := fmt.Sprintf("%dM", memoryMb)
memory := govmmQemu.Memory{
Size: mem,
Slots: defaultMemSlots,
Slots: slots,
MaxMem: memMax,
}

Expand Down
5 changes: 3 additions & 2 deletions virtcontainers/qemu_arch_base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,14 @@ func TestQemuArchBaseMemoryTopology(t *testing.T) {

hostMem := uint64(100)
mem := uint64(120)
slots := uint8(12)
expectedMemory := govmmQemu.Memory{
Size: fmt.Sprintf("%dM", mem),
Slots: defaultMemSlots,
Slots: slots,
MaxMem: fmt.Sprintf("%dM", hostMem),
}

m := qemuArchBase.memoryTopology(mem, hostMem)
m := qemuArchBase.memoryTopology(mem, hostMem, slots)
assert.Equal(expectedMemory, m)
}

Expand Down
4 changes: 2 additions & 2 deletions virtcontainers/qemu_ppc64le.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (q *qemuPPC64le) cpuModel() string {
return cpuModel
}

func (q *qemuPPC64le) memoryTopology(memoryMb, hostMemoryMb uint64) govmmQemu.Memory {
func (q *qemuPPC64le) memoryTopology(memoryMb, hostMemoryMb uint64, slots uint8) govmmQemu.Memory {

if qemuMajorVersion >= 2 && qemuMinorVersion >= 10 {
q.Logger().Debug("Aligning maxmem to multiples of 256MB. Assumption: Kernel Version >= 4.11")
Expand All @@ -119,7 +119,7 @@ func (q *qemuPPC64le) memoryTopology(memoryMb, hostMemoryMb uint64) govmmQemu.Me
hostMemoryMb = defaultMemMaxPPC64le
}

return genericMemoryTopology(memoryMb, hostMemoryMb)
return genericMemoryTopology(memoryMb, hostMemoryMb, slots)
}

func (q *qemuPPC64le) appendImage(devices []govmmQemu.Device, path string) ([]govmmQemu.Device, error) {
Expand Down
5 changes: 3 additions & 2 deletions virtcontainers/qemu_ppc64le_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ func TestQemuPPC64leMemoryTopology(t *testing.T) {

hostMem := uint64(1024)
mem := uint64(120)
slots := uint8(10)
expectedMemory := govmmQemu.Memory{
Size: fmt.Sprintf("%dM", mem),
Slots: defaultMemSlots,
Slots: slots,
MaxMem: fmt.Sprintf("%dM", hostMem+uint64(memoryOffset)),
}

m := ppc64le.memoryTopology(mem, hostMem)
m := ppc64le.memoryTopology(mem, hostMem, slots)
assert.Equal(expectedMemory, m)
}
4 changes: 3 additions & 1 deletion virtcontainers/qemu_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,13 @@ func TestQemuCPUTopology(t *testing.T) {

func TestQemuMemoryTopology(t *testing.T) {
mem := uint32(1000)
slots := uint32(8)

q := &qemu{
arch: &qemuArchBase{},
config: HypervisorConfig{
MemorySize: mem,
MemSlots: slots,
},
}

Expand All @@ -167,7 +169,7 @@ func TestQemuMemoryTopology(t *testing.T) {

expectedOut := govmmQemu.Memory{
Size: fmt.Sprintf("%dM", mem),
Slots: defaultMemSlots,
Slots: uint8(slots),
MaxMem: memMax,
}

Expand Down
3 changes: 2 additions & 1 deletion virtcontainers/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,8 @@ type Cmd struct {
// Resources describes VM resources configuration.
type Resources struct {
// Memory is the amount of available memory in MiB.
Memory uint
Memory uint
MemorySlots uint8
}

// SandboxStatus describes a sandbox status.
Expand Down

0 comments on commit 19801bf

Please sign in to comment.