From: Jiri Denemark <[email protected]> When probing host model CPU we already expand it to get a list of all CPU features. Let's store the expanded CPU definition in virQEMUCaps and copy it to domain capabilities when requested by the VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES flag instead of expanding the CPU over and over on each request.
Signed-off-by: Jiri Denemark <[email protected]> --- Notes: Version 2: - includes misplaced hunks from 2/10 in v1 - supported field renamed as expanded - VIR_QEMU_CAPS_HOST_CPU_SUPPORTED enum value renamed as *_EXPANDED src/qemu/qemu_capabilities.c | 39 ++++++++++++++++++++++++++---------- src/qemu/qemu_capabilities.h | 3 +++ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 26b3e20d71..54cf0d624b 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -795,6 +795,9 @@ struct _virQEMUCapsHostCPUData { unsigned int physAddrSize; /* Host CPU definition reported in domain capabilities. */ virCPUDef *reported; + /* Expanded host CPU definition with features that are implicitly enabled + * by the selected CPU model. */ + virCPUDef *expanded; /* Migratable host CPU definition used for updating guest CPU. */ virCPUDef *migratable; /* CPU definition with features detected by libvirt using virCPUGetHost @@ -1975,6 +1978,9 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUData *dst, if (src->reported) dst->reported = virCPUDefCopy(src->reported); + if (src->expanded) + dst->expanded = virCPUDefCopy(src->expanded); + if (src->migratable) dst->migratable = virCPUDefCopy(src->migratable); @@ -1988,6 +1994,7 @@ virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUData *cpuData) { qemuMonitorCPUModelInfoFree(cpuData->info); virCPUDefFree(cpuData->reported); + virCPUDefFree(cpuData->expanded); virCPUDefFree(cpuData->migratable); virCPUDefFree(cpuData->full); @@ -2314,6 +2321,9 @@ virQEMUCapsGetHostModel(virQEMUCaps *qemuCaps, /* 'full' is non-NULL only if we have data from both QEMU and * virCPUGetHost */ return cpuData->full ? cpuData->full : cpuData->reported; + + case VIR_QEMU_CAPS_HOST_CPU_EXPANDED: + return cpuData->expanded; } return NULL; @@ -2325,6 +2335,7 @@ virQEMUCapsSetHostModel(virQEMUCaps *qemuCaps, virDomainVirtType type, unsigned int physAddrSize, virCPUDef *reported, + virCPUDef *expanded, virCPUDef *migratable, virCPUDef *full) { @@ -2333,6 +2344,7 @@ virQEMUCapsSetHostModel(virQEMUCaps *qemuCaps, cpuData = &virQEMUCapsGetAccel(qemuCaps, type)->hostCPU; cpuData->physAddrSize = physAddrSize; cpuData->reported = reported; + cpuData->expanded = expanded; cpuData->migratable = migratable; cpuData->full = full; } @@ -4136,16 +4148,18 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps, virCPUDefCopyModelFilter(cpu, hostCPU, true, virQEMUCapsCPUFilterFeatures, &qemuCaps->arch); - } else if (virQEMUCapsTypeIsAccelerated(type) && - virCPUGetHostIsSupported(qemuCaps->arch)) { + } + + cpuExpanded = virCPUDefCopy(cpu); + if (virCPUExpandFeatures(qemuCaps->arch, cpuExpanded) < 0) + goto error; + + if (rc == 0 && + virQEMUCapsTypeIsAccelerated(type) && + virCPUGetHostIsSupported(qemuCaps->arch)) { if (!(fullCPU = virQEMUCapsProbeHostCPU(qemuCaps->arch, NULL))) goto error; - cpuExpanded = virCPUDefCopy(cpu); - - if (virCPUExpandFeatures(qemuCaps->arch, cpuExpanded) < 0) - goto error; - for (i = 0; i < cpuExpanded->nfeatures; i++) { if (cpuExpanded->features[i].policy == VIR_CPU_FEATURE_REQUIRE) virCPUDefUpdateFeature(fullCPU, cpuExpanded->features[i].name, @@ -4184,6 +4198,7 @@ virQEMUCapsInitHostCPUModel(virQEMUCaps *qemuCaps, virQEMUCapsSetHostModel(qemuCaps, type, physAddrSize, g_steal_pointer(&cpu), + g_steal_pointer(&cpuExpanded), g_steal_pointer(&migCPU), g_steal_pointer(&fullCPU)); @@ -6640,9 +6655,14 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps, virDomainCaps *domCaps, unsigned int flags) { - virQEMUCapsHostCPUType cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED; + virQEMUCapsHostCPUType cpuType; virCPUDef *cpu; + if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES) + cpuType = VIR_QEMU_CAPS_HOST_CPU_EXPANDED; + else + cpuType = VIR_QEMU_CAPS_HOST_CPU_REPORTED; + cpu = virCPUDefCopy(virQEMUCapsGetHostModel(qemuCaps, domCaps->virttype, cpuType)); @@ -6653,9 +6673,6 @@ virQEMUCapsFillDomainCPUHostModel(virQEMUCaps *qemuCaps, cpu, VIR_CPU_FEATURE_DISABLE); } - if (flags & VIR_CONNECT_GET_DOMAIN_CAPABILITIES_EXPAND_CPU_FEATURES) - virCPUExpandFeatures(domCaps->arch, cpu); - virCPUDefSortFeatures(cpu); domCaps->cpu.hostModel = cpu; } diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index b26b5d3145..b027d37bf3 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -795,6 +795,9 @@ typedef enum { * combined with features reported by QEMU. This is used for backward * compatible comparison between a guest CPU and a host CPU. */ VIR_QEMU_CAPS_HOST_CPU_FULL, + /* Expanded host CPU definition with features that are implicitly enabled + * by the selected CPU model. */ + VIR_QEMU_CAPS_HOST_CPU_EXPANDED, } virQEMUCapsHostCPUType; virCPUDef *virQEMUCapsGetHostModel(virQEMUCaps *qemuCaps, -- 2.54.0
