提交 be9f6ecb 编写于 作者: O Osier Yang

qemu: Set memory policy using cgroup if placement is auto

Like for 'static' placement, when the memory policy mode is
'strict', set the memory policy by writing the advisory nodeset
returned from numad to cgroup file cpuset.mems,
上级 d1bdeca8
...@@ -194,7 +194,8 @@ int qemuSetupHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED, ...@@ -194,7 +194,8 @@ int qemuSetupHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED,
} }
int qemuSetupCgroup(struct qemud_driver *driver, int qemuSetupCgroup(struct qemud_driver *driver,
virDomainObjPtr vm) virDomainObjPtr vm,
char *nodemask)
{ {
virCgroupPtr cgroup = NULL; virCgroupPtr cgroup = NULL;
int rc; int rc;
...@@ -391,10 +392,18 @@ int qemuSetupCgroup(struct qemud_driver *driver, ...@@ -391,10 +392,18 @@ int qemuSetupCgroup(struct qemud_driver *driver,
} }
} }
if (vm->def->numatune.memory.nodemask && if ((vm->def->numatune.memory.nodemask ||
(vm->def->numatune.memory.placement_mode ==
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) &&
vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT && vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
char *mask = virDomainCpuSetFormat(vm->def->numatune.memory.nodemask, VIR_DOMAIN_CPUMASK_LEN); char *mask = NULL;
if (vm->def->numatune.memory.placement_mode ==
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)
mask = virDomainCpuSetFormat(nodemask, VIR_DOMAIN_CPUMASK_LEN);
else
mask = virDomainCpuSetFormat(vm->def->numatune.memory.nodemask,
VIR_DOMAIN_CPUMASK_LEN);
if (!mask) { if (!mask) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, qemuReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to convert memory nodemask")); _("failed to convert memory nodemask"));
......
...@@ -48,7 +48,8 @@ int qemuSetupHostUsbDeviceCgroup(usbDevice *dev, ...@@ -48,7 +48,8 @@ int qemuSetupHostUsbDeviceCgroup(usbDevice *dev,
const char *path, const char *path,
void *opaque); void *opaque);
int qemuSetupCgroup(struct qemud_driver *driver, int qemuSetupCgroup(struct qemud_driver *driver,
virDomainObjPtr vm); virDomainObjPtr vm,
char *nodemask);
int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup, int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup,
unsigned long long period, unsigned long long period,
long long quota); long long quota);
......
...@@ -2537,6 +2537,7 @@ struct qemuProcessHookData { ...@@ -2537,6 +2537,7 @@ struct qemuProcessHookData {
virConnectPtr conn; virConnectPtr conn;
virDomainObjPtr vm; virDomainObjPtr vm;
struct qemud_driver *driver; struct qemud_driver *driver;
char *nodemask;
}; };
static int qemuProcessHook(void *data) static int qemuProcessHook(void *data)
...@@ -2544,8 +2545,6 @@ static int qemuProcessHook(void *data) ...@@ -2544,8 +2545,6 @@ static int qemuProcessHook(void *data)
struct qemuProcessHookData *h = data; struct qemuProcessHookData *h = data;
int ret = -1; int ret = -1;
int fd; int fd;
char *nodeset = NULL;
char *nodemask = NULL;
/* Some later calls want pid present */ /* Some later calls want pid present */
h->vm->pid = getpid(); h->vm->pid = getpid();
...@@ -2575,37 +2574,16 @@ static int qemuProcessHook(void *data) ...@@ -2575,37 +2574,16 @@ static int qemuProcessHook(void *data)
/* This must take place before exec(), so that all QEMU /* This must take place before exec(), so that all QEMU
* memory allocation is on the correct NUMA node * memory allocation is on the correct NUMA node
*/ */
VIR_DEBUG("Moving procss to cgroup"); VIR_DEBUG("Moving process to cgroup");
if (qemuAddToCgroup(h->driver, h->vm->def) < 0) if (qemuAddToCgroup(h->driver, h->vm->def) < 0)
goto cleanup; goto cleanup;
if ((h->vm->def->placement_mode ==
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
(h->vm->def->numatune.memory.placement_mode ==
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) {
nodeset = qemuGetNumadAdvice(h->vm->def);
if (!nodeset)
goto cleanup;
VIR_DEBUG("Nodeset returned from numad: %s", nodeset);
if (VIR_ALLOC_N(nodemask, VIR_DOMAIN_CPUMASK_LEN) < 0) {
virReportOOMError();
goto cleanup;
}
if (virDomainCpuSetParse(nodeset, 0, nodemask,
VIR_DOMAIN_CPUMASK_LEN) < 0)
goto cleanup;
}
/* This must be done after cgroup placement to avoid resetting CPU /* This must be done after cgroup placement to avoid resetting CPU
* affinity */ * affinity */
VIR_DEBUG("Setup CPU affinity"); if (qemuProcessInitCpuAffinity(h->driver, h->vm, h->nodemask) < 0)
if (qemuProcessInitCpuAffinity(h->driver, h->vm, nodemask) < 0)
goto cleanup; goto cleanup;
if (qemuProcessInitNumaMemoryPolicy(h->vm, nodemask) < 0) if (qemuProcessInitNumaMemoryPolicy(h->vm, h->nodemask) < 0)
goto cleanup; goto cleanup;
VIR_DEBUG("Setting up security labelling"); VIR_DEBUG("Setting up security labelling");
...@@ -2616,8 +2594,6 @@ static int qemuProcessHook(void *data) ...@@ -2616,8 +2594,6 @@ static int qemuProcessHook(void *data)
cleanup: cleanup:
VIR_DEBUG("Hook complete ret=%d", ret); VIR_DEBUG("Hook complete ret=%d", ret);
VIR_FREE(nodeset);
VIR_FREE(nodemask);
return ret; return ret;
} }
...@@ -3293,6 +3269,8 @@ int qemuProcessStart(virConnectPtr conn, ...@@ -3293,6 +3269,8 @@ int qemuProcessStart(virConnectPtr conn,
struct qemuProcessHookData hookData; struct qemuProcessHookData hookData;
unsigned long cur_balloon; unsigned long cur_balloon;
int i; int i;
char *nodeset = NULL;
char *nodemask = NULL;
/* Okay, these are just internal flags, /* Okay, these are just internal flags,
* but doesn't hurt to check */ * but doesn't hurt to check */
...@@ -3448,8 +3426,32 @@ int qemuProcessStart(virConnectPtr conn, ...@@ -3448,8 +3426,32 @@ int qemuProcessStart(virConnectPtr conn,
flags & VIR_QEMU_PROCESS_START_COLD) < 0) flags & VIR_QEMU_PROCESS_START_COLD) < 0)
goto cleanup; goto cleanup;
/* Get the advisory nodeset from numad if 'placement' of
* either <vcpu> or <numatune> is 'auto'.
*/
if ((vm->def->placement_mode ==
VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) ||
(vm->def->numatune.memory.placement_mode ==
VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) {
nodeset = qemuGetNumadAdvice(vm->def);
if (!nodeset)
goto cleanup;
VIR_DEBUG("Nodeset returned from numad: %s", nodeset);
if (VIR_ALLOC_N(nodemask, VIR_DOMAIN_CPUMASK_LEN) < 0) {
virReportOOMError();
goto cleanup;
}
if (virDomainCpuSetParse(nodeset, 0, nodemask,
VIR_DOMAIN_CPUMASK_LEN) < 0)
goto cleanup;
}
hookData.nodemask = nodemask;
VIR_DEBUG("Setting up domain cgroup (if required)"); VIR_DEBUG("Setting up domain cgroup (if required)");
if (qemuSetupCgroup(driver, vm) < 0) if (qemuSetupCgroup(driver, vm, nodemask) < 0)
goto cleanup; goto cleanup;
if (VIR_ALLOC(priv->monConfig) < 0) { if (VIR_ALLOC(priv->monConfig) < 0) {
...@@ -3754,6 +3756,8 @@ cleanup: ...@@ -3754,6 +3756,8 @@ cleanup:
/* We jump here if we failed to start the VM for any reason, or /* We jump here if we failed to start the VM for any reason, or
* if we failed to initialize the now running VM. kill it off and * if we failed to initialize the now running VM. kill it off and
* pretend we never started it */ * pretend we never started it */
VIR_FREE(nodeset);
VIR_FREE(nodemask);
virCommandFree(cmd); virCommandFree(cmd);
VIR_FORCE_CLOSE(logfile); VIR_FORCE_CLOSE(logfile);
qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FAILED); qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FAILED);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册