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

View File

@ -357,30 +357,66 @@ virCPUDataFree(virCPUDataPtr data)
/** /**
* cpuNodeData: * virCPUGetHost:
* *
* @arch: CPU architecture * @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 virCPUDefPtr
cpuNodeData(virArch arch) virCPUGetHost(virArch arch,
virNodeInfoPtr nodeInfo)
{ {
struct cpuArchDriver *driver; 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; return NULL;
if (driver->nodeData == NULL) { if (VIR_ALLOC(cpu) < 0)
virReportError(VIR_ERR_NO_SUPPORT,
_("cannot get node CPU data for %s architecture"),
virArchToString(arch));
return NULL; 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 typedef void
(*cpuArchDataFree) (virCPUDataPtr data); (*cpuArchDataFree) (virCPUDataPtr data);
typedef virCPUDataPtr typedef int
(*cpuArchNodeData) (virArch arch); (*virCPUArchGetHost)(virCPUDefPtr cpu);
typedef virCPUDefPtr typedef virCPUDefPtr
(*cpuArchBaseline) (virCPUDefPtr *cpus, (*cpuArchBaseline) (virCPUDefPtr *cpus,
@ -117,7 +117,7 @@ struct cpuArchDriver {
cpuArchDecode decode; cpuArchDecode decode;
cpuArchEncode encode; cpuArchEncode encode;
cpuArchDataFree dataFree; cpuArchDataFree dataFree;
cpuArchNodeData nodeData; virCPUArchGetHost getHost;
cpuArchBaseline baseline; cpuArchBaseline baseline;
virCPUArchUpdate update; virCPUArchUpdate update;
virCPUArchCheckFeature checkFeature; virCPUArchCheckFeature checkFeature;
@ -168,8 +168,9 @@ virCPUDataNew(virArch arch);
void void
virCPUDataFree(virCPUDataPtr data); virCPUDataFree(virCPUDataPtr data);
virCPUDataPtr virCPUDefPtr
cpuNodeData (virArch arch); virCPUGetHost(virArch arch,
virNodeInfoPtr nodeInfo);
char * char *
cpuBaselineXML(const char **xmlCPUs, cpuBaselineXML(const char **xmlCPUs,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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