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>
This commit is contained in:
Jiri Denemark 2017-04-07 18:15:26 +02:00
parent b0605e8487
commit b0a84ffb7f

View File

@ -373,6 +373,19 @@ struct virQEMUCapsMachineType {
unsigned int maxCpus; unsigned int maxCpus;
bool hotplugCpus; 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 * Update the XML parser/formatter when adding more
* information to this struct so that it gets cached * information to this struct so that it gets cached
@ -407,15 +420,8 @@ struct _virQEMUCaps {
size_t ngicCapabilities; size_t ngicCapabilities;
virGICCapability *gicCapabilities; virGICCapability *gicCapabilities;
qemuMonitorCPUModelInfoPtr kvmCPUModelInfo; virQEMUCapsHostCPUData kvmCPU;
qemuMonitorCPUModelInfoPtr tcgCPUModelInfo; virQEMUCapsHostCPUData tcgCPU;
/* 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;
}; };
struct virQEMUCapsSearchData { struct virQEMUCapsSearchData {
@ -2119,23 +2125,15 @@ virQEMUCapsNew(void)
static int static int
virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst, virQEMUCapsHostCPUDataCopy(virQEMUCapsHostCPUDataPtr dst,
virQEMUCapsPtr src) virQEMUCapsHostCPUDataPtr src)
{ {
if (src->kvmCPUModel && if (src->info &&
!(dst->kvmCPUModel = virCPUDefCopy(src->kvmCPUModel))) !(dst->info = qemuMonitorCPUModelInfoCopy(src->info)))
return -1; return -1;
if (src->tcgCPUModel && if (src->reported &&
!(dst->tcgCPUModel = virCPUDefCopy(src->tcgCPUModel))) !(dst->reported = virCPUDefCopy(src->reported)))
return -1;
if (src->kvmCPUModelInfo &&
!(dst->kvmCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->kvmCPUModelInfo)))
return -1;
if (src->tcgCPUModelInfo &&
!(dst->tcgCPUModelInfo = qemuMonitorCPUModelInfoCopy(src->tcgCPUModelInfo)))
return -1; return -1;
return 0; return 0;
@ -2143,17 +2141,12 @@ virQEMUCapsHostCPUDataCopy(virQEMUCapsPtr dst,
static void static void
virQEMUCapsHostCPUDataClear(virQEMUCapsPtr qemuCaps) virQEMUCapsHostCPUDataClear(virQEMUCapsHostCPUDataPtr cpuData)
{ {
qemuMonitorCPUModelInfoFree(qemuCaps->kvmCPUModelInfo); qemuMonitorCPUModelInfoFree(cpuData->info);
qemuMonitorCPUModelInfoFree(qemuCaps->tcgCPUModelInfo); virCPUDefFree(cpuData->reported);
qemuCaps->kvmCPUModelInfo = NULL;
qemuCaps->tcgCPUModelInfo = NULL;
virCPUDefFree(qemuCaps->kvmCPUModel); memset(cpuData, 0, sizeof(*cpuData));
virCPUDefFree(qemuCaps->tcgCPUModel);
qemuCaps->kvmCPUModel = NULL;
qemuCaps->tcgCPUModel = NULL;
} }
@ -2194,7 +2187,8 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
goto error; goto error;
} }
if (virQEMUCapsHostCPUDataCopy(ret, qemuCaps) < 0) if (virQEMUCapsHostCPUDataCopy(&ret->kvmCPU, &qemuCaps->kvmCPU) < 0 ||
virQEMUCapsHostCPUDataCopy(&ret->tcgCPU, &qemuCaps->tcgCPU) < 0)
goto error; goto error;
if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0) if (VIR_ALLOC_N(ret->machineTypes, qemuCaps->nmachineTypes) < 0)
@ -2243,7 +2237,8 @@ void virQEMUCapsDispose(void *obj)
VIR_FREE(qemuCaps->gicCapabilities); VIR_FREE(qemuCaps->gicCapabilities);
virQEMUCapsHostCPUDataClear(qemuCaps); virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU);
virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU);
} }
void void
@ -2467,14 +2462,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 virCPUDefPtr
virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps, virQEMUCapsGetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type) virDomainVirtType type)
{ {
if (type == VIR_DOMAIN_VIRT_KVM) virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
return qemuCaps->kvmCPUModel;
else return cpuData->reported;
return qemuCaps->tcgCPUModel;
} }
@ -2483,10 +2488,9 @@ virQEMUCapsSetHostModel(virQEMUCapsPtr qemuCaps,
virDomainVirtType type, virDomainVirtType type,
virCPUDefPtr cpu) virCPUDefPtr cpu)
{ {
if (type == VIR_DOMAIN_VIRT_KVM) virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
qemuCaps->kvmCPUModel = cpu;
else cpuData->reported = cpu;
qemuCaps->tcgCPUModel = cpu;
} }
@ -2882,24 +2886,28 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon, qemuMonitorPtr mon,
bool tcg) bool tcg)
{ {
qemuMonitorCPUModelInfoPtr *modelInfo; qemuMonitorCPUModelInfoPtr modelInfo = NULL;
qemuMonitorCPUModelInfoPtr nonMigratable = NULL; qemuMonitorCPUModelInfoPtr nonMigratable = NULL;
virHashTablePtr hash = NULL; virHashTablePtr hash = NULL;
const char *model; const char *model;
qemuMonitorCPUModelExpansionType type; qemuMonitorCPUModelExpansionType type;
virDomainVirtType virtType;
virQEMUCapsHostCPUDataPtr cpuData;
int ret = -1; int ret = -1;
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION)) if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_CPU_MODEL_EXPANSION))
return 0; return 0;
if (tcg || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) { if (tcg || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
modelInfo = &qemuCaps->tcgCPUModelInfo; virtType = VIR_DOMAIN_VIRT_QEMU;
model = "max"; model = "max";
} else { } else {
modelInfo = &qemuCaps->kvmCPUModelInfo; virtType = VIR_DOMAIN_VIRT_KVM;
model = "host"; model = "host";
} }
cpuData = virQEMUCapsGetHostCPUData(qemuCaps, virtType);
/* Some x86_64 features defined in cpu_map.xml use spelling which differ /* 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 * 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 * preferred spelling, thus we need to do a full expansion on the result of
@ -2910,14 +2918,14 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
else else
type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC; type = QEMU_MONITOR_CPU_MODEL_EXPANSION_STATIC;
if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, modelInfo) < 0) if (qemuMonitorGetCPUModelExpansion(mon, type, model, true, &modelInfo) < 0)
return -1; goto cleanup;
/* Try to check migratability of each feature. */ /* Try to check migratability of each feature. */
if (*modelInfo && if (modelInfo &&
qemuMonitorGetCPUModelExpansion(mon, type, model, false, qemuMonitorGetCPUModelExpansion(mon, type, model, false,
&nonMigratable) < 0) &nonMigratable) < 0)
goto error; goto cleanup;
if (nonMigratable) { if (nonMigratable) {
qemuMonitorCPUPropertyPtr prop; qemuMonitorCPUPropertyPtr prop;
@ -2925,12 +2933,12 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
size_t i; size_t i;
if (!(hash = virHashCreate(0, NULL))) if (!(hash = virHashCreate(0, NULL)))
goto error; goto cleanup;
for (i = 0; i < (*modelInfo)->nprops; i++) { for (i = 0; i < modelInfo->nprops; i++) {
prop = (*modelInfo)->props + i; prop = modelInfo->props + i;
if (virHashAddEntry(hash, prop->name, prop) < 0) if (virHashAddEntry(hash, prop->name, prop) < 0)
goto error; goto cleanup;
} }
for (i = 0; i < nonMigratable->nprops; i++) { for (i = 0; i < nonMigratable->nprops; i++) {
@ -2948,21 +2956,18 @@ virQEMUCapsProbeQMPHostCPU(virQEMUCapsPtr qemuCaps,
} }
} }
(*modelInfo)->migratability = true; modelInfo->migratability = true;
} }
VIR_STEAL_PTR(cpuData->info, modelInfo);
ret = 0; ret = 0;
cleanup: cleanup:
virHashFree(hash); virHashFree(hash);
qemuMonitorCPUModelInfoFree(nonMigratable); qemuMonitorCPUModelInfoFree(nonMigratable);
qemuMonitorCPUModelInfoFree(modelInfo);
return ret; return ret;
error:
qemuMonitorCPUModelInfoFree(*modelInfo);
*modelInfo = NULL;
goto cleanup;
} }
struct tpmTypeToCaps { struct tpmTypeToCaps {
@ -3315,21 +3320,19 @@ virQEMUCapsInitCPUModel(virQEMUCapsPtr qemuCaps,
virCPUDefPtr cpu, virCPUDefPtr cpu,
bool migratable) bool migratable)
{ {
qemuMonitorCPUModelInfoPtr model; virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
int ret = 1; int ret = 1;
if (type == VIR_DOMAIN_VIRT_KVM) if (migratable && cpuData->info && !cpuData->info->migratability)
model = qemuCaps->kvmCPUModelInfo;
else
model = qemuCaps->tcgCPUModelInfo;
if (migratable && model && !model->migratability)
return 1; return 1;
if (ARCH_IS_S390(qemuCaps->arch)) if (ARCH_IS_S390(qemuCaps->arch)) {
ret = virQEMUCapsInitCPUModelS390(qemuCaps, model, cpu, migratable); ret = virQEMUCapsInitCPUModelS390(qemuCaps, cpuData->info,
else if (ARCH_IS_X86(qemuCaps->arch)) cpu, migratable);
ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, model, cpu, migratable); } else if (ARCH_IS_X86(qemuCaps->arch)) {
ret = virQEMUCapsInitCPUModelX86(qemuCaps, type, cpuData->info,
cpu, migratable);
}
if (ret == 0) if (ret == 0)
cpu->fallback = VIR_CPU_FALLBACK_FORBID; cpu->fallback = VIR_CPU_FALLBACK_FORBID;
@ -3389,10 +3392,9 @@ virQEMUCapsSetCPUModelInfo(virQEMUCapsPtr qemuCaps,
virDomainVirtType type, virDomainVirtType type,
qemuMonitorCPUModelInfoPtr modelInfo) qemuMonitorCPUModelInfoPtr modelInfo)
{ {
if (type == VIR_DOMAIN_VIRT_KVM) virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
qemuCaps->kvmCPUModelInfo = modelInfo;
else cpuData->info = modelInfo;
qemuCaps->tcgCPUModelInfo = modelInfo;
} }
@ -3851,18 +3853,11 @@ virQEMUCapsFormatHostCPUModelInfo(virQEMUCapsPtr qemuCaps,
virBufferPtr buf, virBufferPtr buf,
virDomainVirtType type) virDomainVirtType type)
{ {
qemuMonitorCPUModelInfoPtr model; virQEMUCapsHostCPUDataPtr cpuData = virQEMUCapsGetHostCPUData(qemuCaps, type);
const char *typeStr; qemuMonitorCPUModelInfoPtr model = cpuData->info;
const char *typeStr = type == VIR_DOMAIN_VIRT_KVM ? "kvm" : "tcg";
size_t i; size_t i;
if (type == VIR_DOMAIN_VIRT_KVM) {
typeStr = "kvm";
model = qemuCaps->kvmCPUModelInfo;
} else {
typeStr = "tcg";
model = qemuCaps->tcgCPUModelInfo;
}
if (!model) if (!model)
return; return;
@ -4121,7 +4116,8 @@ virQEMUCapsReset(virQEMUCapsPtr qemuCaps)
VIR_FREE(qemuCaps->gicCapabilities); VIR_FREE(qemuCaps->gicCapabilities);
qemuCaps->ngicCapabilities = 0; qemuCaps->ngicCapabilities = 0;
virQEMUCapsHostCPUDataClear(qemuCaps); virQEMUCapsHostCPUDataClear(&qemuCaps->kvmCPU);
virQEMUCapsHostCPUDataClear(&qemuCaps->tcgCPU);
} }