43fe83
From 968218c6e4261b824efc41515a93fd2fe9878cbc Mon Sep 17 00:00:00 2001
43fe83
Message-Id: <968218c6e4261b824efc41515a93fd2fe9878cbc.1383922566.git.jdenemar@redhat.com>
43fe83
From: Peter Krempa <pkrempa@redhat.com>
43fe83
Date: Fri, 8 Nov 2013 12:33:29 +0100
43fe83
Subject: [PATCH] cpu: x86: Parse the CPU feature map only once
43fe83
43fe83
https://bugzilla.redhat.com/show_bug.cgi?id=1008989
43fe83
43fe83
Until now the map was loaded from the XML definition file every time a
43fe83
operation on the flags was requested. With the introduciton of one shot
43fe83
initializers we can store the definition forever (as it will never
43fe83
change) instead of parsing it over and over again.
43fe83
43fe83
(cherry-picked from commit 629aff378f15df47f93f96b4a2ad780da8aa4785)
43fe83
43fe83
Conflicts:
43fe83
	src/cpu/cpu_x86.c - d4952d36 was not backported and thus the new
43fe83
    flag is not yet in the code
43fe83
43fe83
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
43fe83
---
43fe83
 src/cpu/cpu_x86.c | 65 +++++++++++++++++++++++++++++++++----------------------
43fe83
 1 file changed, 39 insertions(+), 26 deletions(-)
43fe83
43fe83
diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
43fe83
index e5de667..d4d3731 100644
43fe83
--- a/src/cpu/cpu_x86.c
43fe83
+++ b/src/cpu/cpu_x86.c
43fe83
@@ -70,6 +70,10 @@ struct x86_map {
43fe83
     struct x86_model *models;
43fe83
 };
43fe83
 
43fe83
+static struct x86_map* virCPUx86Map = NULL;
43fe83
+int virCPUx86MapOnceInit(void);
43fe83
+VIR_ONCE_GLOBAL_INIT(virCPUx86Map);
43fe83
+
43fe83
 
43fe83
 enum compare_result {
43fe83
     SUBSET,
43fe83
@@ -1119,7 +1123,7 @@ x86MapLoadCallback(enum cpuMapElement element,
43fe83
 
43fe83
 
43fe83
 static struct x86_map *
43fe83
-x86LoadMap(void)
43fe83
+virCPUx86LoadMap(void)
43fe83
 {
43fe83
     struct x86_map *map;
43fe83
 
43fe83
@@ -1137,6 +1141,26 @@ error:
43fe83
 }
43fe83
 
43fe83
 
43fe83
+int
43fe83
+virCPUx86MapOnceInit(void)
43fe83
+{
43fe83
+    if (!(virCPUx86Map = virCPUx86LoadMap()))
43fe83
+        return -1;
43fe83
+
43fe83
+    return 0;
43fe83
+}
43fe83
+
43fe83
+
43fe83
+static const struct x86_map *
43fe83
+virCPUx86GetMap(void)
43fe83
+{
43fe83
+    if (virCPUx86MapInitialize() < 0)
43fe83
+        return NULL;
43fe83
+
43fe83
+    return virCPUx86Map;
43fe83
+}
43fe83
+
43fe83
+
43fe83
 static char *
43fe83
 x86CPUDataFormat(const virCPUData *data)
43fe83
 {
43fe83
@@ -1247,7 +1271,7 @@ x86Compute(virCPUDefPtr host,
43fe83
            virCPUDataPtr *guest,
43fe83
            char **message)
43fe83
 {
43fe83
-    struct x86_map *map = NULL;
43fe83
+    const struct x86_map *map = NULL;
43fe83
     struct x86_model *host_model = NULL;
43fe83
     struct x86_model *cpu_force = NULL;
43fe83
     struct x86_model *cpu_require = NULL;
43fe83
@@ -1300,7 +1324,7 @@ x86Compute(virCPUDefPtr host,
43fe83
         return VIR_CPU_COMPARE_INCOMPATIBLE;
43fe83
     }
43fe83
 
43fe83
-    if (!(map = x86LoadMap()) ||
43fe83
+    if (!(map = virCPUx86GetMap()) ||
43fe83
         !(host_model = x86ModelFromCPU(host, map, VIR_CPU_FEATURE_REQUIRE)) ||
43fe83
         !(cpu_force = x86ModelFromCPU(cpu, map, VIR_CPU_FEATURE_FORCE)) ||
43fe83
         !(cpu_require = x86ModelFromCPU(cpu, map, VIR_CPU_FEATURE_REQUIRE)) ||
43fe83
@@ -1376,7 +1400,6 @@ x86Compute(virCPUDefPtr host,
43fe83
     }
43fe83
 
43fe83
 cleanup:
43fe83
-    x86MapFree(map);
43fe83
     x86ModelFree(host_model);
43fe83
     x86ModelFree(diff);
43fe83
     x86ModelFree(cpu_force);
43fe83
@@ -1421,13 +1444,13 @@ x86Decode(virCPUDefPtr cpu,
43fe83
           const char *preferred)
43fe83
 {
43fe83
     int ret = -1;
43fe83
-    struct x86_map *map;
43fe83
+    const struct x86_map *map;
43fe83
     const struct x86_model *candidate;
43fe83
     virCPUDefPtr cpuCandidate;
43fe83
     virCPUDefPtr cpuModel = NULL;
43fe83
     size_t i;
43fe83
 
43fe83
-    if (data == NULL || (map = x86LoadMap()) == NULL)
43fe83
+    if (!data || !(map = virCPUx86GetMap()))
43fe83
         return -1;
43fe83
 
43fe83
     candidate = map->models;
43fe83
@@ -1508,7 +1531,6 @@ x86Decode(virCPUDefPtr cpu,
43fe83
     ret = 0;
43fe83
 
43fe83
 out:
43fe83
-    x86MapFree(map);
43fe83
     virCPUDefFree(cpuModel);
43fe83
 
43fe83
     return ret;
43fe83
@@ -1554,14 +1576,13 @@ x86Encode(virArch arch,
43fe83
           virCPUDataPtr *forbidden,
43fe83
           virCPUDataPtr *vendor)
43fe83
 {
43fe83
-    struct x86_map *map = NULL;
43fe83
+    const struct x86_map *map = NULL;
43fe83
     virCPUx86Data *data_forced = NULL;
43fe83
     virCPUx86Data *data_required = NULL;
43fe83
     virCPUx86Data *data_optional = NULL;
43fe83
     virCPUx86Data *data_disabled = NULL;
43fe83
     virCPUx86Data *data_forbidden = NULL;
43fe83
     virCPUx86Data *data_vendor = NULL;
43fe83
-    int ret = -1;
43fe83
 
43fe83
     if (forced)
43fe83
         *forced = NULL;
43fe83
@@ -1576,7 +1597,7 @@ x86Encode(virArch arch,
43fe83
     if (vendor)
43fe83
         *vendor = NULL;
43fe83
 
43fe83
-    if ((map = x86LoadMap()) == NULL)
43fe83
+    if ((map = virCPUx86GetMap()) == NULL)
43fe83
         goto error;
43fe83
 
43fe83
     if (forced) {
43fe83
@@ -1644,12 +1665,7 @@ x86Encode(virArch arch,
43fe83
         !(*vendor = virCPUx86MakeData(arch, &data_vendor)))
43fe83
         goto error;
43fe83
 
43fe83
-    ret = 0;
43fe83
-
43fe83
-cleanup:
43fe83
-    x86MapFree(map);
43fe83
-
43fe83
-    return ret;
43fe83
+    return 0;
43fe83
 
43fe83
 error:
43fe83
     virCPUx86DataFree(data_forced);
43fe83
@@ -1670,7 +1686,7 @@ error:
43fe83
         x86FreeCPUData(*forbidden);
43fe83
     if (vendor)
43fe83
         x86FreeCPUData(*vendor);
43fe83
-    goto cleanup;
43fe83
+    return -1;
43fe83
 }
43fe83
 
43fe83
 
43fe83
@@ -1769,7 +1785,7 @@ x86Baseline(virCPUDefPtr *cpus,
43fe83
             const char **models,
43fe83
             unsigned int nmodels)
43fe83
 {
43fe83
-    struct x86_map *map = NULL;
43fe83
+    const struct x86_map *map = NULL;
43fe83
     struct x86_model *base_model = NULL;
43fe83
     virCPUDefPtr cpu = NULL;
43fe83
     size_t i;
43fe83
@@ -1777,7 +1793,7 @@ x86Baseline(virCPUDefPtr *cpus,
43fe83
     struct x86_model *model = NULL;
43fe83
     bool outputVendor = true;
43fe83
 
43fe83
-    if (!(map = x86LoadMap()))
43fe83
+    if (!(map = virCPUx86GetMap()))
43fe83
         goto error;
43fe83
 
43fe83
     if (!(base_model = x86ModelFromCPU(cpus[0], map, VIR_CPU_FEATURE_REQUIRE)))
43fe83
@@ -1858,7 +1874,6 @@ x86Baseline(virCPUDefPtr *cpus,
43fe83
 
43fe83
 cleanup:
43fe83
     x86ModelFree(base_model);
43fe83
-    x86MapFree(map);
43fe83
 
43fe83
     return cpu;
43fe83
 
43fe83
@@ -1876,10 +1891,10 @@ x86UpdateCustom(virCPUDefPtr guest,
43fe83
 {
43fe83
     int ret = -1;
43fe83
     size_t i;
43fe83
-    struct x86_map *map;
43fe83
+    const struct x86_map *map;
43fe83
     struct x86_model *host_model = NULL;
43fe83
 
43fe83
-    if (!(map = x86LoadMap()) ||
43fe83
+    if (!(map = virCPUx86GetMap()) ||
43fe83
         !(host_model = x86ModelFromCPU(host, map, VIR_CPU_FEATURE_REQUIRE)))
43fe83
         goto cleanup;
43fe83
 
43fe83
@@ -1911,7 +1926,6 @@ x86UpdateCustom(virCPUDefPtr guest,
43fe83
     ret = 0;
43fe83
 
43fe83
 cleanup:
43fe83
-    x86MapFree(map);
43fe83
     x86ModelFree(host_model);
43fe83
     return ret;
43fe83
 }
43fe83
@@ -1979,11 +1993,11 @@ x86Update(virCPUDefPtr guest,
43fe83
 static int x86HasFeature(const virCPUDataPtr data,
43fe83
                          const char *name)
43fe83
 {
43fe83
-    struct x86_map *map;
43fe83
+    const struct x86_map *map;
43fe83
     struct x86_feature *feature;
43fe83
     int ret = -1;
43fe83
 
43fe83
-    if (!(map = x86LoadMap()))
43fe83
+    if (!(map = virCPUx86GetMap()))
43fe83
         return -1;
43fe83
 
43fe83
     if (!(feature = x86FeatureFind(map, name)))
43fe83
@@ -1992,7 +2006,6 @@ static int x86HasFeature(const virCPUDataPtr data,
43fe83
     ret = x86DataIsSubset(data->data.x86, feature->data) ? 1 : 0;
43fe83
 
43fe83
 cleanup:
43fe83
-    x86MapFree(map);
43fe83
     return ret;
43fe83
 }
43fe83
 
43fe83
-- 
43fe83
1.8.4.2
43fe83