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