Blob Blame History Raw
From 988e2340fa307179fc6f896af33c4376187b90f8 Mon Sep 17 00:00:00 2001
Message-Id: <988e2340fa307179fc6f896af33c4376187b90f8@dist-git>
From: Jiri Denemark <jdenemar@redhat.com>
Date: Fri, 7 Apr 2017 18:15:26 +0200
Subject: [PATCH] qemu: Move qemuCaps host CPU data in a struct

We need to store several CPU related data structure for both KVM and
TCG. So instead of keeping two different copies of everything let's
make a virQEMUCapsHostCPUData struct and use it twice.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
(cherry picked from commit b0a84ffb7f38f990120c231cfb74956a0ed10d95)

https://bugzilla.redhat.com/show_bug.cgi?id=1444421

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
---
 src/qemu/qemu_capabilities.c | 166 +++++++++++++++++++++----------------------
 1 file changed, 81 insertions(+), 85 deletions(-)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 8e7cbb590..0db149018 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -374,6 +374,19 @@ struct virQEMUCapsMachineType {
     unsigned int maxCpus;
     bool hotplugCpus;
 };
+
+typedef struct _virQEMUCapsHostCPUData virQEMUCapsHostCPUData;
+typedef virQEMUCapsHostCPUData *virQEMUCapsHostCPUDataPtr;
+struct _virQEMUCapsHostCPUData {
+    /* Only the "info" part is stored in the capabilities cache, the rest is
+     * re-computed from other fields and external data sources everytime we
+     * probe QEMU or load the cache.
+     */
+    qemuMonitorCPUModelInfoPtr info;
+    /* Host CPU definition reported in domain capabilities. */
+    virCPUDefPtr reported;
+};
+
 /*
  * Update the XML parser/formatter when adding more
  * information to this struct so that it gets cached
@@ -408,15 +421,8 @@ struct _virQEMUCaps {
     size_t ngicCapabilities;
     virGICCapability *gicCapabilities;
 
-    qemuMonitorCPUModelInfoPtr kvmCPUModelInfo;
-    qemuMonitorCPUModelInfoPtr tcgCPUModelInfo;
-
-    /* Anything below is not stored in the cache since the values are
-     * re-computed from the other fields or external data sources every
-     * time we probe QEMU or load the results from the cache.
-     */
-    virCPUDefPtr kvmCPUModel;
-    virCPUDefPtr tcgCPUModel;
+    virQEMUCapsHostCPUData kvmCPU;
+    virQEMUCapsHostCPUData tcgCPU;
 };
 
 struct virQEMUCapsSearchData {
@@ -2089,23 +2095,15 @@ virQEMUCapsNew(void)
 
 
 static int
-virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
-                           virQEMUCapsPtr src)
+virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
+                           virQEMUCapsHostCPUDataPtr src)
 {
-    if (src->kvmCPUModel &&
-        !(dst->kvmCPUModel = virCPUDefCopy(src->kvmCPUModel)))
+    if (src->info &&
+        !(dst->info = qemuMonitorCPUModelInfoCopy(src->info)))
         return -1;
 
-    if (src->tcgCPUModel &&
-        !(dst->tcgCPUModel = virCPUDefCopy(src->tcgCPUModel)))
-        return -1;
-
-    if (src->kvmCPUModelInfo &&
-        !(dst->kvmCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->kvmCPUModelInfo)))
-        return -1;
-
-    if (src->tcgCPUModelInfo &&
-        !(dst->tcgCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->tcgCPUModelInfo)))
+    if (src->reported &&
+        !(dst->reported = virCPUDefCopy(src->reported)))
         return -1;
 
     return 0;
@@ -2113,17 +2111,12 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
 
 
 static void
-virQEMUCapsHostCPUDataClear(virQEMUCapsPtr qemuCaps)
+virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
 {
-    qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo);
-    qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo);
-    qemuCaps->kvmCPUModelInfo = NULL;
-    qemuCaps->tcgCPUModelInfo = NULL;
+    qemuMonitorCPUModelInfoFree(cpuData->info);
+    virCPUDefFree(cpuData->reported);
 
-    virCPUDefFree(qemuCaps->kvmCPUModel);
-    virCPUDefFree(qemuCaps->tcgCPUModel);
-    qemuCaps->kvmCPUModel = NULL;
-    qemuCaps->tcgCPUModel = NULL;
+    memset(cpuData, 0, sizeof(*cpuData));
 }
 
 
@@ -2164,7 +2157,8 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
             goto error;
     }
 
-    if (virQEMUCapsHostCPUDataCopy(ret, qemuCaps) < 0)
+    if (virQEMUCapsHostCPUDataCopy(&ret->kvmCPU, &qemuCaps->kvmCPU) < 0 ||
+        virQEMUCapsHostCPUDataCopy(&ret->tcgCPU, &qemuCaps->tcgCPU) < 0)
         goto error;
 
     if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
@@ -2213,7 +2207,8 @@ void virQEMUCapsDispose(void *obj)
 
     VIR_FREE(qemuCaps->gicCapabilities);
 
-    virQEMUCapsHostCPUDataClear(qemuCaps);
+    virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU);
+    virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU);
 }
 
 void
@@ -2437,14 +2432,24 @@ virQEMUCapsGetCPUDefinitions(virQEMUCapsPtr qemuCaps,
 }
 
 
+static virQEMUCapsHostCPUDataPtr
+virQEMUCapsGetHostCPUData(virQEMUCapsPtr qemuCaps,
+                          virDomainVirtType type)
+{
+    if (type == VIR_DOMAIN_VIRT_KVM)
+        return &qemuCaps->kvmCPU;
+    else
+        return &qemuCaps->tcgCPU;
+}
+
+
 virCPUDefPtr
 virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
                         virDomainVirtType type)
 {
-    if (type == VIR_DOMAIN_VIRT_KVM)
-        return qemuCaps->kvmCPUModel;
-    else
-        return qemuCaps->tcgCPUModel;
+    virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+    return cpuData->reported;
 }
 
 
@@ -2453,10 +2458,9 @@ virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
                         virDomainVirtType type,
                         virCPUDefPtr cpu)
 {
-    if (type == VIR_DOMAIN_VIRT_KVM)
-        qemuCaps->kvmCPUModel = cpu;
-    else
-        qemuCaps->tcgCPUModel = cpu;
+    virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+    cpuData->reported = cpu;
 }
 
 
@@ -2847,24 +2851,28 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
                            qemuMonitorPtr mon,
                            bool tcg)
 {
-    qemuMonitorCPUModelInfoPtr *modelInfo;
+    qemuMonitorCPUModelInfoPtr modelInfo = NULL;
     qemuMonitorCPUModelInfoPtr nonMigratable = NULL;
     virHashTablePtr hash = NULL;
     const char *model;
     qemuMonitorCPUModelExpansionType type;
+    virDomainVirtType virtType;
+    virQEMUCapsHostCPUDataPtr cpuData;
     int ret = -1;
 
     if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
         return 0;
 
     if (tcg || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
-        modelInfo = &qemuCaps->tcgCPUModelInfo;
+        virtType = VIR_DOMAIN_VIRT_QEMU;
         model = "max";
     } else {
-        modelInfo = &qemuCaps->kvmCPUModelInfo;
+        virtType = VIR_DOMAIN_VIRT_KVM;
         model = "host";
     }
 
+    cpuData = virQEMUCapsGetHostCPUData(qemuCaps, virtType);
+
     /* Some x86_64 features defined in cpu_map.xml use spelling which differ
      * from the one preferred by QEMU. Static expansion would give us only the
      * preferred spelling, thus we need to do a full expansion on the result of
@@ -2875,14 +2883,14 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
     else
         type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC;
 
-    if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, modelInfo) < 0)
-        return -1;
+    if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, &modelInfo) < 0)
+        goto cleanup;
 
     /* Try to check migratability of each feature. */
-    if (*modelInfo &&
+    if (modelInfo &&
         qemuMonitorGetCPUModelExpansion(mon, type, model, false,
                                         &nonMigratable) < 0)
-        goto error;
+        goto cleanup;
 
     if (nonMigratable) {
         qemuMonitorCPUPropertyPtr prop;
@@ -2890,12 +2898,12 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
         size_t i;
 
         if (!(hash = virHashCreate(0, NULL)))
-            goto error;
+            goto cleanup;
 
-        for (i = 0; i < (*modelInfo)->nprops; i++) {
-            prop = (*modelInfo)->props + i;
+        for (i = 0; i < modelInfo->nprops; i++) {
+            prop = modelInfo->props + i;
             if (virHashAddEntry(hash, prop->name, prop) < 0)
-                goto error;
+                goto cleanup;
         }
 
         for (i = 0; i < nonMigratable->nprops; i++) {
@@ -2913,21 +2921,18 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
             }
         }
 
-        (*modelInfo)->migratability = true;
+        modelInfo->migratability = true;
     }
 
+    VIR_STEAL_PTR(cpuData->info, modelInfo);
     ret = 0;
 
  cleanup:
     virHashFree(hash);
     qemuMonitorCPUModelInfoFree(nonMigratable);
+    qemuMonitorCPUModelInfoFree(modelInfo);
 
     return ret;
-
- error:
-    qemuMonitorCPUModelInfoFree(*modelInfo);
-    *modelInfo = NULL;
-    goto cleanup;
 }
 
 struct tpmTypeToCaps {
@@ -3280,21 +3285,19 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
                         virCPUDefPtr cpu,
                         bool migratable)
 {
-    qemuMonitorCPUModelInfoPtr model;
+    virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
     int ret = 1;
 
-    if (type == VIR_DOMAIN_VIRT_KVM)
-        model = qemuCaps->kvmCPUModelInfo;
-    else
-        model = qemuCaps->tcgCPUModelInfo;
-
-    if (migratable && model && !model->migratability)
+    if (migratable && cpuData->info && !cpuData->info->migratability)
         return 1;
 
-    if (ARCH_IS_S390(qemuCaps->arch))
-        ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu, migratable);
-    else if (ARCH_IS_X86(qemuCaps->arch))
-        ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu, migratable);
+    if (ARCH_IS_S390(qemuCaps->arch)) {
+        ret = virQEMUCapsInitCPUModelS390(qemuCaps, cpuData->info,
+                                          cpu, migratable);
+    } else if (ARCH_IS_X86(qemuCaps->arch)) {
+        ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpuData->info,
+                                         cpu, migratable);
+    }
 
     if (ret == 0)
         cpu->fallback = VIR_CPU_FALLBACK_FORBID;
@@ -3354,10 +3357,9 @@ virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
                            virDomainVirtType type,
                            qemuMonitorCPUModelInfoPtr modelInfo)
 {
-    if (type == VIR_DOMAIN_VIRT_KVM)
-        qemuCaps->kvmCPUModelInfo = modelInfo;
-    else
-        qemuCaps->tcgCPUModelInfo = modelInfo;
+    virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+
+    cpuData->info = modelInfo;
 }
 
 
@@ -3816,18 +3818,11 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
                                   virBufferPtr buf,
                                   virDomainVirtType type)
 {
-    qemuMonitorCPUModelInfoPtr model;
-    const char *typeStr;
+    virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
+    qemuMonitorCPUModelInfoPtr model = cpuData->info;
+    const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg";
     size_t i;
 
-    if (type == VIR_DOMAIN_VIRT_KVM) {
-        typeStr = "kvm";
-        model = qemuCaps->kvmCPUModelInfo;
-    } else {
-        typeStr = "tcg";
-        model = qemuCaps->tcgCPUModelInfo;
-    }
-
     if (!model)
         return;
 
@@ -4086,7 +4081,8 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
     VIR_FREE(qemuCaps->gicCapabilities);
     qemuCaps->ngicCapabilities = 0;
 
-    virQEMUCapsHostCPUDataClear(qemuCaps);
+    virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU);
+    virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU);
 }
 
 
-- 
2.12.2