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

Reply via email to