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