From c4ded6ee5e48ff911be83229c2885a5ab7a3b1d7 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 27 Aug 2018 13:55:24 +0800 Subject: [PATCH 1/2] qemu: refactor maximum vcpus supported in aarch64 on aarch64, we support different gic interrupt controllers. The maximum number of vCPUs depends on the GIC version, or on how many redistributors we can fit into the memory map. Fixes: #584 Signed-off-by: Penny Zheng Signed-off-by: Wei Chen --- virtcontainers/qemu_arm64.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/virtcontainers/qemu_arm64.go b/virtcontainers/qemu_arm64.go index 112631b09b..9385a533b5 100644 --- a/virtcontainers/qemu_arm64.go +++ b/virtcontainers/qemu_arm64.go @@ -107,8 +107,22 @@ func getGuestGICVersion() (version string) { return "host" } +//In qemu, maximum number of vCPUs depends on the GIC version, or on how +//many redistributors we can fit into the memory map. +//related codes are under github.com/qemu/qemu/hw/arm/virt.c(Line 135 and 1306 in stable-2.11) +//for now, qemu only supports v2 and v3, we treat v4 as v3 based on +//backward compatibility. +var gicList = map[uint32]uint32{ + uint32(2): uint32(8), + uint32(3): uint32(123), + uint32(4): uint32(123), +} + // MaxQemuVCPUs returns the maximum number of vCPUs supported func MaxQemuVCPUs() uint32 { + if hostGICVersion != 0 { + return gicList[hostGICVersion] + } return uint32(runtime.NumCPU()) } From 2d13c4653d7a5bb6469da149dc7d02f0466ea432 Mon Sep 17 00:00:00 2001 From: root Date: Mon, 27 Aug 2018 15:08:06 +0800 Subject: [PATCH 2/2] test: add unit test for func MaxQemuVCPUs we should add unit test for func MaxQemuVCPUS in qemu_amd64_test.go Signed-off-by: Penny Zheng Signed-off-by: Wei Chen --- virtcontainers/qemu_arm64_test.go | 53 +++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/virtcontainers/qemu_arm64_test.go b/virtcontainers/qemu_arm64_test.go index 17aaa5f7a3..30f3568010 100644 --- a/virtcontainers/qemu_arm64_test.go +++ b/virtcontainers/qemu_arm64_test.go @@ -7,6 +7,10 @@ package virtcontainers import ( "fmt" + "io/ioutil" + "os" + "path/filepath" + "runtime" "testing" govmmQemu "github.com/intel/govmm/qemu" @@ -50,3 +54,52 @@ func TestQemuArm64MemoryTopology(t *testing.T) { m := arm64.memoryTopology(mem, hostMem) assert.Equal(expectedMemory, m) } + +func TestMaxQemuVCPUs(t *testing.T) { + assert := assert.New(t) + + type testData struct { + contents string + expectedResult uint32 + } + + data := []testData{ + {"", uint32(runtime.NumCPU())}, + {" 1: 0 0 GICv2 25 Level vgic \n", uint32(8)}, + {" 1: 0 0 GICv3 25 Level vgic \n", uint32(123)}, + {" 1: 0 0 GICv4 25 Level vgic \n", uint32(123)}, + } + + tmpdir, err := ioutil.TempDir("", "") + if err != nil { + panic(err) + } + defer os.RemoveAll(tmpdir) + + savedGicProfile := gicProfile + + testGicProfile := filepath.Join(tmpdir, "interrupts") + + // override + gicProfile = testGicProfile + + defer func() { + gicProfile = savedGicProfile + }() + + savedHostGICVersion := hostGICVersion + + defer func() { + hostGICVersion = savedHostGICVersion + }() + + for _, d := range data { + err := ioutil.WriteFile(gicProfile, []byte(d.contents), os.FileMode(0640)) + assert.NoError(err) + + hostGICVersion = getHostGICVersion() + vCPUs := MaxQemuVCPUs() + + assert.Equal(d.expectedResult, vCPUs) + } +}