return NULL;
}
+
+
+void
+qemuDomainNumatuneMaybeFormatNodesetUnion(virDomainObj *vm,
+ virBitmap **nodeset,
+ char **nodesetStr)
+{
+ virDomainNuma *numatune = vm->def->numa;
+ qemuDomainObjPrivate *priv = vm->privateData;
+ g_autoptr(virBitmap) unionMask = virBitmapNew(0);
+ ssize_t i;
+
+ for (i = -1; i < (ssize_t)virDomainNumaGetNodeCount(numatune); i++) {
+ virBitmap *tmp;
+
+ tmp = virDomainNumatuneGetNodeset(numatune, priv->autoNodeset, i);
+ if (tmp)
+ virBitmapUnion(unionMask, tmp);
+ }
+
+ if (nodesetStr)
+ *nodesetStr = virBitmapFormat(unionMask);
+
+ if (nodeset)
+ *nodeset = g_steal_pointer(&unionMask);
+}
virBitmap *cpumask,
unsigned long long period,
long long quota,
- virDomainThreadSchedParam *sched)
+ virDomainThreadSchedParam *sched,
+ bool unionMems)
{
qemuDomainObjPrivate *priv = vm->privateData;
virDomainNuma *numatune = vm->def->numa;
if (virDomainNumatuneGetMode(numatune, -1, &mem_mode) == 0 &&
(mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT ||
- mem_mode == VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE) &&
- virDomainNumatuneMaybeFormatNodeset(numatune,
- priv->autoNodeset,
- &mem_mask, -1) < 0)
- goto cleanup;
+ mem_mode == VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE)) {
+
+ /* QEMU allocates its memory from the emulator thread. Thus it
+ * needs to access union of all host nodes configured. This is
+ * going to be replaced with proper value later in the startup
+ * process. */
+ if (unionMems &&
+ nameval == VIR_CGROUP_THREAD_EMULATOR &&
+ mem_mode != VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE) {
+ qemuDomainNumatuneMaybeFormatNodesetUnion(vm, NULL, &mem_mask);
+ } else {
+ if (virDomainNumatuneMaybeFormatNodeset(numatune,
+ priv->autoNodeset,
+ &mem_mask, -1) < 0)
+ goto cleanup;
+ }
+ }
/* For restrictive numatune mode we need to set cpuset.mems for vCPU
* threads based on the node they are in as there is nothing else uses
static int
-qemuProcessSetupEmulator(virDomainObj *vm)
+qemuProcessSetupEmulator(virDomainObj *vm,
+ bool unionMems)
{
return qemuProcessSetupPid(vm, vm->pid, VIR_CGROUP_THREAD_EMULATOR,
0, vm->def->cputune.emulatorpin,
vm->def->cputune.emulator_period,
vm->def->cputune.emulator_quota,
- vm->def->cputune.emulatorsched);
+ vm->def->cputune.emulatorsched,
+ unionMems);
}
vcpuid, vcpu->cpumask,
vm->def->cputune.period,
vm->def->cputune.quota,
- &vcpu->sched) < 0)
+ &vcpu->sched,
+ false) < 0)
return -1;
if (schedCore &&
iothread->cpumask,
vm->def->cputune.iothread_period,
vm->def->cputune.iothread_quota,
- &iothread->sched);
+ &iothread->sched,
+ false);
}
goto cleanup;
VIR_DEBUG("Setting emulator tuning/settings");
- if (qemuProcessSetupEmulator(vm) < 0)
+ if (qemuProcessSetupEmulator(vm, true) < 0)
goto cleanup;
VIR_DEBUG("Setting cgroup for external devices (if required)");
if (qemuConnectAgent(driver, vm) < 0)
goto cleanup;
+ VIR_DEBUG("Fixing up emulator tuning/settings");
+ if (qemuProcessSetupEmulator(vm, false) < 0)
+ goto cleanup;
+
VIR_DEBUG("setting up hotpluggable cpus");
if (qemuDomainHasHotpluggableStartupVcpus(vm->def)) {
if (qemuDomainRefreshVcpuInfo(vm, asyncJob, false) < 0)