From 17b3021b54da9e9fe570d260a662cf46bbb6bb8d Mon Sep 17 00:00:00 2001 From: Jia He Date: Sun, 28 Jun 2020 20:43:16 -0700 Subject: [PATCH] Subject: [PATCH] qemu: arm64: Don't detect gic version by /proc/interrupts [ port from runtime repository commit 4d4a153af5cb145215cb6e6e386eac2bcb8c3e32 ] Commit b4385901daf5 ("qemu/arm64: Detect host GIC version to configure guest GIC") reads /proc/interrupts to detect the host gic version. But on a ThunderX2 host with 224 cpus, the /proc/interrupts is ~762K bytes. Hence it will costs ~900K bytes memory overhead. From the go tool pprof results: flat flat% sum% cum cum% 976.89kB 100% 100% 976.89kB 100% github.com/kata-containers/runtime/virtcontainers.getHostGICVersion Although the allocated memory will be freed, seems it worthy removing that for speed up the runtime. As per [1], there is no perfect way to detect the gic version on host. At qemu side, if we use "gic-version=host", qemu will automatically detect the verion by kvm ioctl. So we'd better let qemu determine the gic version. If the user really want to start vm with gic-verion=2, he/she can set it in machine_accelerators option. [1]https://lists.cs.columbia.edu/pipermail/kvmarm/2014-October/011690.html Signed-off-by: Jia He Signed-off-by: Peng Tao --- src/runtime/virtcontainers/qemu_arm64.go | 85 +++--------------------- 1 file changed, 10 insertions(+), 75 deletions(-) diff --git a/src/runtime/virtcontainers/qemu_arm64.go b/src/runtime/virtcontainers/qemu_arm64.go index 78de84fa71..ed38457711 100644 --- a/src/runtime/virtcontainers/qemu_arm64.go +++ b/src/runtime/virtcontainers/qemu_arm64.go @@ -8,13 +8,10 @@ package virtcontainers import ( "context" "fmt" - "io/ioutil" "runtime" - "strings" "time" govmmQemu "github.com/intel/govmm/qemu" - "github.com/sirupsen/logrus" ) type qemuArm64 struct { @@ -28,7 +25,7 @@ const defaultQemuMachineType = QemuVirt const qmpMigrationWaitTimeout = 10 * time.Second -var defaultQemuMachineOptions = "usb=off,accel=kvm,gic-version=" + getGuestGICVersion() +const defaultQemuMachineOptions = "usb=off,accel=kvm,gic-version=host" var kernelParams = []Param{ {"console", "hvc0"}, @@ -36,70 +33,11 @@ var kernelParams = []Param{ {"iommu.passthrough", "0"}, } -var supportedQemuMachine = govmmQemu.Machine { +var supportedQemuMachine = govmmQemu.Machine{ Type: QemuVirt, Options: defaultQemuMachineOptions, } -// Logger returns a logrus logger appropriate for logging qemu-aarch64 messages -func qemuArmLogger() *logrus.Entry { - return virtLog.WithField("subsystem", "qemu-aarch64") -} - -// On ARM platform, we have different GIC interrupt controllers. Different -// GIC supports different QEMU parameters for virtual GIC and max VCPUs -var hostGICVersion = getHostGICVersion() - -// We will access this file on host to detect host GIC version -var gicProfile = "/proc/interrupts" - -// Detect the host GIC version. -// Success: return the number of GIC version -// Failed: return 0 -func getHostGICVersion() (version uint32) { - bytes, err := ioutil.ReadFile(gicProfile) - if err != nil { - qemuArmLogger().WithField("GIC profile", gicProfile).WithError(err).Error("Failed to parse GIC profile") - return 0 - } - - s := string(bytes) - if strings.Contains(s, "GICv2") { - return 2 - } - - if strings.Contains(s, "GICv3") { - return 3 - } - - if strings.Contains(s, "GICv4") { - return 4 - } - - return 0 -} - -// QEMU supports GICv2, GICv3 and host parameters for gic-version. The host -// parameter will let QEMU detect GIC version by itself. This parameter -// will work properly when host GIC version is GICv2 or GICv3. But the -// detection will failed when host GIC is gicv4 or higher. In this case, -// we have to detect the host GIC version manually and force QEMU to use -// GICv3 when host GIC is GICv4 or higher. -func getGuestGICVersion() (version string) { - if hostGICVersion == 2 { - return "2" - } - - if hostGICVersion >= 3 { - return "3" - } - - // We can't parse valid host GIC version from GIC profile. - // But we can use "host" to ask QEMU to detect valid GIC - // through KVM API for a try. - 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) @@ -113,9 +51,6 @@ var gicList = map[uint32]uint32{ // MaxQemuVCPUs returns the maximum number of vCPUs supported func MaxQemuVCPUs() uint32 { - if hostGICVersion != 0 { - return gicList[hostGICVersion] - } return uint32(runtime.NumCPU()) } @@ -131,14 +66,14 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) { q := &qemuArm64{ qemuArchBase{ - qemuMachine: supportedQemuMachine, - qemuExePath: defaultQemuPath, - memoryOffset: config.MemOffset, - kernelParamsNonDebug: kernelParamsNonDebug, - kernelParamsDebug: kernelParamsDebug, - kernelParams: kernelParams, - disableNvdimm: config.DisableImageNvdimm, - dax: true, + qemuMachine: supportedQemuMachine, + qemuExePath: defaultQemuPath, + memoryOffset: config.MemOffset, + kernelParamsNonDebug: kernelParamsNonDebug, + kernelParamsDebug: kernelParamsDebug, + kernelParams: kernelParams, + disableNvdimm: config.DisableImageNvdimm, + dax: true, }, }