提交 99123ba0 编写于 作者: D Daniel P. Berrange

Fix QEMU cpu affinity at startup to include all threads

The QEMU cpu affinity is used in NUMA scenarios to ensure that
guest memory is allocated from a specific node. Normally memory
is allocate on demand in vCPU threads, but when using hugepages
the initial thread leader allocates memory upfront. libvirt was
not setting affinity of the thread leader, or I/O threads. This
patch changes the code to set the process affinity in between
the fork()/exec() of QEMU. This ensures that every single QEMU
thread gets the affinity

* src/qemu/qemu_driver.c: Set affinity on entire QEMU process
  at startup
上级 05e15ff8
...@@ -1929,6 +1929,9 @@ qemuDetectVcpuPIDs(struct qemud_driver *driver, ...@@ -1929,6 +1929,9 @@ qemuDetectVcpuPIDs(struct qemud_driver *driver,
return 0; return 0;
} }
/*
* To be run between fork/exec of QEMU only
*/
static int static int
qemudInitCpuAffinity(virDomainObjPtr vm) qemudInitCpuAffinity(virDomainObjPtr vm)
{ {
...@@ -1936,7 +1939,8 @@ qemudInitCpuAffinity(virDomainObjPtr vm) ...@@ -1936,7 +1939,8 @@ qemudInitCpuAffinity(virDomainObjPtr vm)
virNodeInfo nodeinfo; virNodeInfo nodeinfo;
unsigned char *cpumap; unsigned char *cpumap;
int cpumaplen; int cpumaplen;
qemuDomainObjPrivatePtr priv = vm->privateData;
DEBUG0("Setting CPU affinity");
if (nodeGetInfo(NULL, &nodeinfo) < 0) if (nodeGetInfo(NULL, &nodeinfo) < 0)
return -1; return -1;
...@@ -1968,14 +1972,14 @@ qemudInitCpuAffinity(virDomainObjPtr vm) ...@@ -1968,14 +1972,14 @@ qemudInitCpuAffinity(virDomainObjPtr vm)
VIR_USE_CPU(cpumap, i); VIR_USE_CPU(cpumap, i);
} }
/* The XML config only gives a per-VM affinity, so we apply /* We are pressuming we are running between fork/exec of QEMU
* the same mapping to all vCPUs */ * so use '0' to indicate our own process ID. No threads are
for (i = 0 ; i < priv->nvcpupids ; i++) { * running at this point
if (virProcessInfoSetAffinity(priv->vcpupids[i], */
cpumap, cpumaplen, maxcpu) < 0) { if (virProcessInfoSetAffinity(0, /* Self */
VIR_FREE(cpumap); cpumap, cpumaplen, maxcpu) < 0) {
return -1; VIR_FREE(cpumap);
} return -1;
} }
VIR_FREE(cpumap); VIR_FREE(cpumap);
...@@ -2896,6 +2900,12 @@ struct qemudHookData { ...@@ -2896,6 +2900,12 @@ struct qemudHookData {
static int qemudSecurityHook(void *data) { static int qemudSecurityHook(void *data) {
struct qemudHookData *h = data; struct qemudHookData *h = data;
/* This must take place before exec(), so that all QEMU
* memory allocation is on the correct NUMA node
*/
if (qemudInitCpuAffinity(h->vm) < 0)
return -1;
if (qemuAddToCgroup(h->driver, h->vm->def) < 0) if (qemuAddToCgroup(h->driver, h->vm->def) < 0)
return -1; return -1;
...@@ -3202,10 +3212,6 @@ static int qemudStartVMDaemon(virConnectPtr conn, ...@@ -3202,10 +3212,6 @@ static int qemudStartVMDaemon(virConnectPtr conn,
if (qemuDetectVcpuPIDs(driver, vm) < 0) if (qemuDetectVcpuPIDs(driver, vm) < 0)
goto abort; goto abort;
DEBUG0("Setting CPU affinity");
if (qemudInitCpuAffinity(vm) < 0)
goto abort;
DEBUG0("Setting any required VM passwords"); DEBUG0("Setting any required VM passwords");
if (qemuInitPasswords(conn, driver, vm, qemuCmdFlags) < 0) if (qemuInitPasswords(conn, driver, vm, qemuCmdFlags) < 0)
goto abort; goto abort;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册