* src/qemu/qemu_process.c (New function qemuProcessInitNumaPolicy, and invoke it in function qemuProcessHook) --- src/qemu/qemu_process.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 98 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index bd7c932..43d793c 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -28,6 +28,10 @@ #include <sys/time.h> #include <sys/resource.h> +#if HAVE_NUMACTL +# include <numa.h> +#endif + #include "qemu_process.h" #include "qemu_domain.h" #include "qemu_cgroup.h" @@ -1081,6 +1085,97 @@ qemuProcessDetectVcpuPIDs(struct qemud_driver *driver, } /* + * Set Numa policy for qemu process, to be run between fork/exec of + * QEMU only. + */ +#if HAVA_NUMACTL +static int +qemuProcessInitNumaPolicy(virDomainObjPtr vm) +{ + struct bitmask mask = NULL; + virErrorPtr orig_err = NULL; + virErrorPtr err = NULL; + int model = -1; + int node = -1; + int ret = -1; + int i = 0; + + if (!vm->def->numatune.memory.nodeset) + return 0; + + model = vm->def->numatune.memory.model; + mask = numa_parse_nodestring(vm->def->numatune.memory.nodeset); + + orig_err = virSaveLastError(); + + if (model == VIR_DOMAIN_NUMATUNE_MEM_STRICT) { + numa_set_bind_policy(1); + numa_set_membind(mask); + numa_set_bind_policy(0); + + err = virGetLastError(); + if ((err && (err->code != orig_err->code)) || + (err && !orig_err)) { + VIR_ERROR(_("Failed to bind memory to nodeset '%s': %s"), + vm->def->numatune.memory.nodeset, + err ? err->message : _("unknown error")); + virResetLastError(err); + goto cleanup; + } + } else if (model == VIR_DOMAIN_NUMATUNE_MEM_PREFERRED) { + for (i=0; i<mask->size; i++) { + if (numa_bitmask_isbitset(mask, i)) + node = i; + } + + numa_set_bind_policy(0); + numa_set_preferred(node); + + err = virGetLastError(); + if ((err && (err->code != orig_err->code)) || + (err && !orig_err)) { + VIR_ERROR(_("Failed to set memory policy as preferred to node " + "'%s': %s"), vm->def->numatune.memory.nodeset, + err ? err->message : _("unknown error")); + virResetLastError(err); + goto cleanup; + } + } else if (model == VIR_DOMAIN_NUMATUNE_MEM_INTERLEAVE) { + numa_set_interleave_mask(mask); + + err = virGetLastError(); + if ((err && (err->code != orig_err->code)) || + (err && !orig_err)) { + VIR_ERROR(_("Failed to interleave memory to nodeset '%s': %s"), + vm->def->numatune.memory.nodeset, + err ? err->message : _("unknown error")); + virResetLastError(err); + goto cleanup; + } + } else { + /* XXX: Shouldn't go here, as we already do checking when + * parsing domain XML. + */ + qemuReportError(VIR_ERR_XML_ERROR, + "%s", _("Invalid model for memory NUMA tuning.")); + goto cleanup; + } + + ret = 0; + +cleanup: + numa_bitmask_free(mask); + return ret; +} +#else +static int +qemuProcessInitNumaPolicy(virDomainObjPtr vm ATTRIBUTE_UNUSED) +{ + return 0; +} +#endif + +/* * To be run between fork/exec of QEMU only */ static int @@ -1789,6 +1884,9 @@ static int qemuProcessHook(void *data) if (qemuProcessInitCpuAffinity(h->vm) < 0) return -1; + if (qemuProcessInitNumaPolicy(h->vm) < 0) + return -1; + if (virSecurityManagerSetProcessLabel(h->driver->securityManager, h->vm) < 0) return -1; -- 1.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list