Skip to content

Commit

Permalink
Subject: [PATCH] qemu: arm64: Don't detect gic version by /proc/inter…
Browse files Browse the repository at this point in the history
…rupts

[ port from runtime repository commit 4d4a153 ]

Commit b438590 ("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 <[email protected]>
Signed-off-by: Peng Tao <[email protected]>
  • Loading branch information
justin-he authored and bergwolf committed Jun 29, 2020
1 parent 4cda90a commit 17b3021
Showing 1 changed file with 10 additions and 75 deletions.
85 changes: 10 additions & 75 deletions src/runtime/virtcontainers/qemu_arm64.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -28,78 25,19 @@ 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"},
{"console", "hvc1"},
{"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)
Expand All @@ -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())
}

Expand All @@ -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,
},
}

Expand Down

0 comments on commit 17b3021

Please sign in to comment.