cpu: Replace cpuNodeData with virCPUGetHost

cpuNodeData has always been followed by cpuDecode as no hypervisor
driver is really interested in raw CPUID data for a host CPU. Let's
create a new CPU driver API which returns virCPUDefPtr directly.

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
This commit is contained in:
Jiri Denemark 2017-03-06 21:35:49 +01:00
parent 5cbc247e0d
commit 23a3f5f50c
11 changed files with 95 additions and 139 deletions

View File

@ -43,41 +43,17 @@ VIR_LOG_INIT("bhyve.bhyve_capabilities");
static int
virBhyveCapsInitCPU(virCapsPtr caps,
virArch arch)
virArch arch)
{
virCPUDefPtr cpu = NULL;
virCPUDataPtr data = NULL;
virNodeInfo nodeinfo;
int ret = -1;
if (VIR_ALLOC(cpu) < 0)
goto error;
cpu->arch = arch;
if (nodeGetInfo(&nodeinfo))
goto error;
return -1;
cpu->type = VIR_CPU_TYPE_HOST;
cpu->sockets = nodeinfo.sockets;
cpu->cores = nodeinfo.cores;
cpu->threads = nodeinfo.threads;
caps->host.cpu = cpu;
if (!(caps->host.cpu = virCPUGetHost(arch, &nodeinfo)))
return -1;
if (!(data = cpuNodeData(arch)) ||
cpuDecode(cpu, data, NULL, 0, NULL) < 0)
goto cleanup;
ret = 0;
cleanup:
virCPUDataFree(data);
return ret;
error:
virCPUDefFree(cpu);
goto cleanup;
return 0;
}
virCapsPtr

View File

@ -357,30 +357,66 @@ virCPUDataFree(virCPUDataPtr data)
/**
* cpuNodeData:
* virCPUGetHost:
*
* @arch: CPU architecture
* @nodeInfo: simplified CPU topology (optional)
*
* Returns CPU data for host CPU or NULL on error.
* Create CPU definition describing the host's CPU. If @nodeInfo is not NULL,
* the CPU definition will have topology (sockets, cores, threads) filled in
* according to the content of @nodeInfo. The function fails only if @nodeInfo
* was not passed in and the assigned CPU driver was not able to detect the
* host CPU model. In other words, a CPU definition containing just the
* topology is a successful result even if detecting the host CPU model fails.
*
* Returns host CPU definition or NULL on error.
*/
virCPUDataPtr
cpuNodeData(virArch arch)
virCPUDefPtr
virCPUGetHost(virArch arch,
virNodeInfoPtr nodeInfo)
{
struct cpuArchDriver *driver;
virCPUDefPtr cpu = NULL;
VIR_DEBUG("arch=%s", virArchToString(arch));
VIR_DEBUG("arch=%s, nodeInfo=%p",
virArchToString(arch), nodeInfo);
if ((driver = cpuGetSubDriver(arch)) == NULL)
if (!(driver = cpuGetSubDriver(arch)))
return NULL;
if (driver->nodeData == NULL) {
virReportError(VIR_ERR_NO_SUPPORT,
_("cannot get node CPU data for %s architecture"),
virArchToString(arch));
if (VIR_ALLOC(cpu) < 0)
return NULL;
cpu->arch = arch;
cpu->type = VIR_CPU_TYPE_HOST;
if (nodeInfo) {
cpu->sockets = nodeInfo->sockets;
cpu->cores = nodeInfo->cores;
cpu->threads = nodeInfo->threads;
}
return driver->nodeData(arch);
/* Try to get the host CPU model, but don't really fail if nodeInfo is
* filled in.
*/
if (driver->getHost) {
if (driver->getHost(cpu) < 0 && !nodeInfo)
goto error;
} else if (nodeInfo) {
VIR_DEBUG("cannot detect host CPU model for %s architecture",
virArchToString(arch));
} else {
virReportError(VIR_ERR_NO_SUPPORT,
_("cannot detect host CPU model for %s architecture"),
virArchToString(arch));
goto error;
}
return cpu;
error:
virCPUDefFree(cpu);
return NULL;
}

View File

@ -70,8 +70,8 @@ typedef int
typedef void
(*cpuArchDataFree) (virCPUDataPtr data);
typedef virCPUDataPtr
(*cpuArchNodeData) (virArch arch);
typedef int
(*virCPUArchGetHost)(virCPUDefPtr cpu);
typedef virCPUDefPtr
(*cpuArchBaseline) (virCPUDefPtr *cpus,
@ -117,7 +117,7 @@ struct cpuArchDriver {
cpuArchDecode decode;
cpuArchEncode encode;
cpuArchDataFree dataFree;
cpuArchNodeData nodeData;
virCPUArchGetHost getHost;
cpuArchBaseline baseline;
virCPUArchUpdate update;
virCPUArchCheckFeature checkFeature;
@ -168,8 +168,9 @@ virCPUDataNew(virArch arch);
void
virCPUDataFree(virCPUDataPtr data);
virCPUDataPtr
cpuNodeData (virArch arch);
virCPUDefPtr
virCPUGetHost(virArch arch,
virNodeInfoPtr nodeInfo);
char *
cpuBaselineXML(const char **xmlCPUs,

View File

@ -111,7 +111,6 @@ struct cpuArchDriver cpuDriverArm = {
.compare = virCPUarmCompare,
.decode = NULL,
.encode = NULL,
.nodeData = NULL,
.baseline = armBaseline,
.update = virCPUarmUpdate,
};

View File

@ -714,19 +714,21 @@ virCPUppc64DataFree(virCPUDataPtr data)
VIR_FREE(data);
}
static virCPUDataPtr
ppc64DriverNodeData(virArch arch)
static int
virCPUppc64GetHost(virCPUDefPtr cpu)
{
virCPUDataPtr nodeData;
virCPUDataPtr cpuData = NULL;
virCPUppc64Data *data;
int ret = -1;
if (VIR_ALLOC(nodeData) < 0)
goto error;
if (!(cpuData = virCPUDataNew(archs[0])))
goto cleanup;
data = &nodeData->data.ppc64;
data = &cpuData->data.ppc64;
if (VIR_ALLOC_N(data->pvr, 1) < 0)
goto error;
goto cleanup;
data->len = 1;
@ -736,13 +738,11 @@ ppc64DriverNodeData(virArch arch)
#endif
data->pvr[0].mask = 0xfffffffful;
nodeData->arch = arch;
ret = ppc64DriverDecode(cpu, cpuData, NULL, 0, NULL, 0);
return nodeData;
error:
virCPUppc64DataFree(nodeData);
return NULL;
cleanup:
virCPUppc64DataFree(cpuData);
return ret;
}
@ -902,7 +902,7 @@ struct cpuArchDriver cpuDriverPPC64 = {
.decode = ppc64DriverDecode,
.encode = NULL,
.dataFree = virCPUppc64DataFree,
.nodeData = ppc64DriverNodeData,
.getHost = virCPUppc64GetHost,
.baseline = ppc64DriverBaseline,
.update = virCPUppc64Update,
.getModels = virCPUppc64DriverGetModels,

View File

@ -109,7 +109,6 @@ struct cpuArchDriver cpuDriverS390 = {
.compare = virCPUs390Compare,
.decode = NULL,
.encode = NULL,
.nodeData = NULL,
.baseline = NULL,
.update = virCPUs390Update,
};

View File

@ -2437,25 +2437,24 @@ cpuidSet(uint32_t base, virCPUDataPtr data)
}
static virCPUDataPtr
x86NodeData(virArch arch)
static int
virCPUx86GetHost(virCPUDefPtr cpu)
{
virCPUDataPtr cpuData = NULL;
int ret = -1;
if (!(cpuData = virCPUDataNew(arch)))
goto error;
if (!(cpuData = virCPUDataNew(archs[0])))
goto cleanup;
if (cpuidSet(CPUX86_BASIC, cpuData) < 0)
goto error;
if (cpuidSet(CPUX86_BASIC, cpuData) < 0 ||
cpuidSet(CPUX86_EXTENDED, cpuData) < 0)
goto cleanup;
if (cpuidSet(CPUX86_EXTENDED, cpuData) < 0)
goto error;
ret = x86DecodeCPUData(cpu, cpuData, NULL, 0, NULL, 0);
return cpuData;
error:
cleanup:
virCPUx86DataFree(cpuData);
return NULL;
return ret;
}
#endif
@ -2849,9 +2848,7 @@ struct cpuArchDriver cpuDriverX86 = {
.encode = x86Encode,
.dataFree = virCPUx86DataFree,
#if defined(__i386__) || defined(__x86_64__)
.nodeData = x86NodeData,
#else
.nodeData = NULL,
.getHost = virCPUx86GetHost,
#endif
.baseline = x86Baseline,
.update = virCPUx86Update,

View File

@ -996,7 +996,6 @@ cpuBaseline;
cpuBaselineXML;
cpuDecode;
cpuEncode;
cpuNodeData;
virCPUCheckFeature;
virCPUCompare;
virCPUCompareXML;
@ -1006,6 +1005,7 @@ virCPUDataFormat;
virCPUDataFree;
virCPUDataNew;
virCPUDataParse;
virCPUGetHost;
virCPUGetModels;
virCPUTranslate;
virCPUUpdate;

View File

@ -1065,39 +1065,15 @@ static int
virQEMUCapsInitCPU(virCapsPtr caps,
virArch arch)
{
virCPUDefPtr cpu = NULL;
virCPUDataPtr data = NULL;
virNodeInfo nodeinfo;
int ret = -1;
if (VIR_ALLOC(cpu) < 0)
goto error;
cpu->arch = arch;
if (nodeGetInfo(&nodeinfo))
goto error;
return -1;
cpu->type = VIR_CPU_TYPE_HOST;
cpu->sockets = nodeinfo.sockets;
cpu->cores = nodeinfo.cores;
cpu->threads = nodeinfo.threads;
caps->host.cpu = cpu;
if (!(caps->host.cpu = virCPUGetHost(arch, &nodeinfo)))
return -1;
if (!(data = cpuNodeData(arch))
|| cpuDecode(cpu, data, NULL, 0, NULL) < 0)
goto cleanup;
ret = 0;
cleanup:
virCPUDataFree(data);
return ret;
error:
virCPUDefFree(cpu);
goto cleanup;
return 0;
}

View File

@ -62,7 +62,6 @@ vmwareCapsInit(void)
virCapsPtr caps = NULL;
virCapsGuestPtr guest = NULL;
virCPUDefPtr cpu = NULL;
virCPUDataPtr data = NULL;
if ((caps = virCapabilitiesNew(virArchFromHost(),
false, false)) == NULL)
@ -83,26 +82,18 @@ vmwareCapsInit(void)
NULL, NULL, 0, NULL) == NULL)
goto error;
if (VIR_ALLOC(cpu) < 0)
if (!(cpu = virCPUGetHost(caps->host.arch, NULL)))
goto error;
cpu->arch = caps->host.arch;
cpu->type = VIR_CPU_TYPE_HOST;
if (!(data = cpuNodeData(cpu->arch))
|| cpuDecode(cpu, data, NULL, 0, NULL) < 0) {
goto error;
}
/* x86_64 guests are supported if
* - Host arch is x86_64
* Or
* - Host CPU is x86_64 with virtualization extensions
*/
if (caps->host.arch == VIR_ARCH_X86_64 ||
(virCPUDataCheckFeature(data, "lm") &&
(virCPUDataCheckFeature(data, "vmx") ||
virCPUDataCheckFeature(data, "svm")))) {
(virCPUCheckFeature(cpu->arch, cpu, "lm") &&
(virCPUCheckFeature(cpu->arch, cpu, "vmx") ||
virCPUCheckFeature(cpu->arch, cpu, "svm")))) {
if ((guest = virCapabilitiesAddGuest(caps,
VIR_DOMAIN_OSTYPE_HVM,
@ -118,8 +109,6 @@ vmwareCapsInit(void)
cleanup:
virCPUDefFree(cpu);
virCPUDataFree(data);
return caps;
error:

View File

@ -99,8 +99,6 @@ static virCapsPtr
vzBuildCapabilities(void)
{
virCapsPtr caps = NULL;
virCPUDefPtr cpu = NULL;
virCPUDataPtr data = NULL;
virNodeInfo nodeinfo;
virDomainOSType ostypes[] = {
VIR_DOMAIN_OSTYPE_HVM,
@ -131,32 +129,17 @@ vzBuildCapabilities(void)
if (nodeGetInfo(&nodeinfo))
goto error;
if (VIR_ALLOC(cpu) < 0)
if (!(caps->host.cpu = virCPUGetHost(caps->host.arch, &nodeinfo)))
goto error;
cpu->arch = caps->host.arch;
cpu->type = VIR_CPU_TYPE_HOST;
cpu->sockets = nodeinfo.sockets;
cpu->cores = nodeinfo.cores;
cpu->threads = nodeinfo.threads;
caps->host.cpu = cpu;
if (virCapabilitiesAddHostMigrateTransport(caps, "vzmigr") < 0)
goto error;
if (!(data = cpuNodeData(cpu->arch))
|| cpuDecode(cpu, data, NULL, 0, NULL) < 0) {
goto cleanup;
}
cleanup:
virCPUDataFree(data);
return caps;
error:
virObjectUnref(caps);
goto cleanup;
return NULL;
}
static void vzDriverDispose(void * obj)