mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-04-30 20:54:26 +00:00
Subject: [PATCH] qemu: arm64: Don't detect gic version by /proc/interrupts
[ port from runtime repository commit 4d4a153af5cb145215cb6e6e386eac2bcb8c3e32 ]
Commit b4385901da
("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 <justin.he@arm.com>
Signed-off-by: Peng Tao <bergwolf@hyper.sh>
This commit is contained in:
parent
4cda90abcb
commit
17b3021b54
@ -8,13 +8,10 @@ package virtcontainers
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
govmmQemu "github.com/intel/govmm/qemu"
|
govmmQemu "github.com/intel/govmm/qemu"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type qemuArm64 struct {
|
type qemuArm64 struct {
|
||||||
@ -28,7 +25,7 @@ const defaultQemuMachineType = QemuVirt
|
|||||||
|
|
||||||
const qmpMigrationWaitTimeout = 10 * time.Second
|
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{
|
var kernelParams = []Param{
|
||||||
{"console", "hvc0"},
|
{"console", "hvc0"},
|
||||||
@ -36,70 +33,11 @@ var kernelParams = []Param{
|
|||||||
{"iommu.passthrough", "0"},
|
{"iommu.passthrough", "0"},
|
||||||
}
|
}
|
||||||
|
|
||||||
var supportedQemuMachine = govmmQemu.Machine {
|
var supportedQemuMachine = govmmQemu.Machine{
|
||||||
Type: QemuVirt,
|
Type: QemuVirt,
|
||||||
Options: defaultQemuMachineOptions,
|
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
|
//In qemu, maximum number of vCPUs depends on the GIC version, or on how
|
||||||
//many redistributors we can fit into the memory map.
|
//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)
|
//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
|
// MaxQemuVCPUs returns the maximum number of vCPUs supported
|
||||||
func MaxQemuVCPUs() uint32 {
|
func MaxQemuVCPUs() uint32 {
|
||||||
if hostGICVersion != 0 {
|
|
||||||
return gicList[hostGICVersion]
|
|
||||||
}
|
|
||||||
return uint32(runtime.NumCPU())
|
return uint32(runtime.NumCPU())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,14 +66,14 @@ func newQemuArch(config HypervisorConfig) (qemuArch, error) {
|
|||||||
|
|
||||||
q := &qemuArm64{
|
q := &qemuArm64{
|
||||||
qemuArchBase{
|
qemuArchBase{
|
||||||
qemuMachine: supportedQemuMachine,
|
qemuMachine: supportedQemuMachine,
|
||||||
qemuExePath: defaultQemuPath,
|
qemuExePath: defaultQemuPath,
|
||||||
memoryOffset: config.MemOffset,
|
memoryOffset: config.MemOffset,
|
||||||
kernelParamsNonDebug: kernelParamsNonDebug,
|
kernelParamsNonDebug: kernelParamsNonDebug,
|
||||||
kernelParamsDebug: kernelParamsDebug,
|
kernelParamsDebug: kernelParamsDebug,
|
||||||
kernelParams: kernelParams,
|
kernelParams: kernelParams,
|
||||||
disableNvdimm: config.DisableImageNvdimm,
|
disableNvdimm: config.DisableImageNvdimm,
|
||||||
dax: true,
|
dax: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user