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, --- src/qemu/qemu_cgroup.c | 15 +++++++++-- src/qemu/qemu_cgroup.h | 3 +- src/qemu/qemu_process.c | 62 +++++++++++++++++++++++++---------------------- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index a07b6cd..f8f375f 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -194,7 +194,8 @@ int qemuSetupHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED, } int qemuSetupCgroup(struct qemud_driver *driver, - virDomainObjPtr vm) + virDomainObjPtr vm, + char *nodemask) { virCgroupPtr cgroup = NULL; int rc; @@ -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 && 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) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("failed to convert memory nodemask")); diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h index 17164d9..c1023b3 100644 --- a/src/qemu/qemu_cgroup.h +++ b/src/qemu/qemu_cgroup.h @@ -48,7 +48,8 @@ int qemuSetupHostUsbDeviceCgroup(usbDevice *dev, const char *path, void *opaque); int qemuSetupCgroup(struct qemud_driver *driver, - virDomainObjPtr vm); + virDomainObjPtr vm, + char *nodemask); int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup, unsigned long long period, long long quota); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index d226067..19bb22a 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2544,6 +2544,7 @@ struct qemuProcessHookData { virConnectPtr conn; virDomainObjPtr vm; struct qemud_driver *driver; + char *nodemask; }; static int qemuProcessHook(void *data) @@ -2551,8 +2552,6 @@ static int qemuProcessHook(void *data) struct qemuProcessHookData *h = data; int ret = -1; int fd; - char *nodeset = NULL; - char *nodemask = NULL; /* Some later calls want pid present */ h->vm->pid = getpid(); @@ -2582,37 +2581,16 @@ static int qemuProcessHook(void *data) /* This must take place before exec(), so that all QEMU * 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) 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 * affinity */ - VIR_DEBUG("Setup CPU affinity"); - if (qemuProcessInitCpuAffinity(h->driver, h->vm, nodemask) < 0) + if (qemuProcessInitCpuAffinity(h->driver, h->vm, h->nodemask) < 0) goto cleanup; - if (qemuProcessInitNumaMemoryPolicy(h->vm, nodemask) < 0) + if (qemuProcessInitNumaMemoryPolicy(h->vm, h->nodemask) < 0) goto cleanup; VIR_DEBUG("Setting up security labelling"); @@ -2623,8 +2601,6 @@ static int qemuProcessHook(void *data) cleanup: VIR_DEBUG("Hook complete ret=%d", ret); - VIR_FREE(nodeset); - VIR_FREE(nodemask); return ret; } @@ -3300,6 +3276,8 @@ int qemuProcessStart(virConnectPtr conn, struct qemuProcessHookData hookData; unsigned long cur_balloon; int i; + char *nodeset = NULL; + char *nodemask = NULL; /* Okay, these are just internal flags, * but doesn't hurt to check */ @@ -3455,8 +3433,32 @@ int qemuProcessStart(virConnectPtr conn, flags & VIR_QEMU_PROCESS_START_COLD) < 0) 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)"); - if (qemuSetupCgroup(driver, vm) < 0) + if (qemuSetupCgroup(driver, vm, nodemask) < 0) goto cleanup; if (VIR_ALLOC(priv->monConfig) < 0) { @@ -3761,6 +3763,8 @@ cleanup: /* 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 * pretend we never started it */ + VIR_FREE(nodeset); + VIR_FREE(nodemask); virCommandFree(cmd); VIR_FORCE_CLOSE(logfile); qemuProcessStop(driver, vm, 0, VIR_DOMAIN_SHUTOFF_FAILED); -- 1.7.7.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list