提交 0039a32f 编写于 作者: O Osier Yang

qemu: Add helper to prepare cpumap for affinity setting

Abstract the codes to prepare cpumap into a helper a function,
which can be used later.

* src/qemu/qemu_process.h: Declare qemuPrepareCpumap
* src/qemu/qemu_process.c: Implement qemuPrepareCpumap, and use it.
上级 08842171
...@@ -1890,23 +1890,20 @@ qemuGetNumadAdvice(virDomainDefPtr def ATTRIBUTE_UNUSED) ...@@ -1890,23 +1890,20 @@ qemuGetNumadAdvice(virDomainDefPtr def ATTRIBUTE_UNUSED)
} }
#endif #endif
/* /* Helper to prepare cpumap for affinity setting, convert
* To be run between fork/exec of QEMU only * NUMA nodeset into cpuset if @nodemask is not NULL, otherwise
* just return a new allocated bitmap.
*/ */
static int virBitmapPtr
qemuProcessInitCpuAffinity(struct qemud_driver *driver, qemuPrepareCpumap(struct qemud_driver *driver,
virDomainObjPtr vm,
virBitmapPtr nodemask) virBitmapPtr nodemask)
{ {
int ret = -1;
int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN; int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN;
virNodeInfo nodeinfo; virNodeInfo nodeinfo;
virBitmapPtr cpumap, cpumapToSet; virBitmapPtr cpumap = NULL;
VIR_DEBUG("Setting CPU affinity");
if (nodeGetInfo(NULL, &nodeinfo) < 0) if (nodeGetInfo(NULL, &nodeinfo) < 0)
return -1; return NULL;
/* setaffinity fails if you set bits for CPUs which /* setaffinity fails if you set bits for CPUs which
* aren't present, so we have to limit ourselves */ * aren't present, so we have to limit ourselves */
...@@ -1914,34 +1911,57 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver, ...@@ -1914,34 +1911,57 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
if (maxcpu > hostcpus) if (maxcpu > hostcpus)
maxcpu = hostcpus; maxcpu = hostcpus;
cpumap = virBitmapNew(maxcpu); if (!(cpumap = virBitmapNew(maxcpu))) {
if (!cpumap) {
virReportOOMError(); virReportOOMError();
return -1; return NULL;
} }
cpumapToSet = cpumap; if (nodemask) {
if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
VIR_DEBUG("Set CPU affinity with advisory nodeset from numad");
/* numad returns the NUMA node list, convert it to cpumap */
for (i = 0; i < driver->caps->host.nnumaCell; i++) { for (i = 0; i < driver->caps->host.nnumaCell; i++) {
int j; int j;
int cur_ncpus = driver->caps->host.numaCell[i]->ncpus; int cur_ncpus = driver->caps->host.numaCell[i]->ncpus;
bool result; bool result;
if (virBitmapGetBit(nodemask, i, &result) < 0) if (virBitmapGetBit(nodemask, i, &result) < 0) {
goto cleanup; virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Failed to covert nodeset to cpuset"));
virBitmapFree(cpumap);
return NULL;
}
if (result) { if (result) {
for (j = 0; j < cur_ncpus; j++) for (j = 0; j < cur_ncpus; j++)
ignore_value(virBitmapSetBit(cpumap, ignore_value(virBitmapSetBit(cpumap,
driver->caps->host.numaCell[i]->cpus[j])); driver->caps->host.numaCell[i]->cpus[j]));
} }
} }
}
return cpumap;
}
/*
* To be run between fork/exec of QEMU only
*/
static int
qemuProcessInitCpuAffinity(struct qemud_driver *driver,
virDomainObjPtr vm,
virBitmapPtr nodemask)
{
int ret = -1;
virBitmapPtr cpumap = NULL;
virBitmapPtr cpumapToSet = NULL;
if (!(cpumap = qemuPrepareCpumap(driver, nodemask)))
return -1;
if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) {
VIR_DEBUG("Set CPU affinity with advisory nodeset from numad");
cpumapToSet = cpumap;
} else { } else {
VIR_DEBUG("Set CPU affinity with specified cpuset"); VIR_DEBUG("Set CPU affinity with specified cpuset");
if (vm->def->cpumask) { if (vm->def->cpumask) {
cpumapToSet = vm->def->cpumask; cpumapToSet = vm->def->cpumask;
} else { } else {
cpumapToSet = cpumap;
/* You may think this is redundant, but we can't assume libvirtd /* You may think this is redundant, but we can't assume libvirtd
* itself is running on all pCPUs, so we need to explicitly set * itself is running on all pCPUs, so we need to explicitly set
* the spawned QEMU instance to all pCPUs if no map is given in * the spawned QEMU instance to all pCPUs if no map is given in
......
...@@ -96,5 +96,7 @@ int qemuProcessAutoDestroyRemove(struct qemud_driver *driver, ...@@ -96,5 +96,7 @@ int qemuProcessAutoDestroyRemove(struct qemud_driver *driver,
virDomainObjPtr vm); virDomainObjPtr vm);
bool qemuProcessAutoDestroyActive(struct qemud_driver *driver, bool qemuProcessAutoDestroyActive(struct qemud_driver *driver,
virDomainObjPtr vm); virDomainObjPtr vm);
virBitmapPtr qemuPrepareCpumap(struct qemud_driver *driver,
virBitmapPtr nodemask);
#endif /* __QEMU_PROCESS_H__ */ #endif /* __QEMU_PROCESS_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册