return -1;
}
-int
-qemuSetupCgroupForIOThreads(virDomainObjPtr vm)
-{
- virCgroupPtr cgroup_iothread = NULL;
- qemuDomainObjPrivatePtr priv = vm->privateData;
- virDomainDefPtr def = vm->def;
- size_t i;
- unsigned long long period = vm->def->cputune.period;
- long long quota = vm->def->cputune.quota;
- char *mem_mask = NULL;
- virDomainNumatuneMemMode mem_mode;
-
- if (def->niothreadids == 0)
- return 0;
-
- if ((period || quota) &&
- !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("cgroup cpu is required for scheduler tuning"));
- return -1;
- }
-
- /*
- * If CPU cgroup controller is not initialized here, then we need
- * neither period nor quota settings. And if CPUSET controller is
- * not initialized either, then there's nothing to do anyway.
- */
- if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU) &&
- !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET))
- return 0;
-
- if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
- mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
- virDomainNumatuneMaybeFormatNodeset(vm->def->numa,
- priv->autoNodeset,
- &mem_mask, -1) < 0)
- goto cleanup;
-
- for (i = 0; i < def->niothreadids; i++) {
- /* IOThreads are numbered 1..n, although the array is 0..n-1,
- * so we will account for that here
- */
- if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_IOTHREAD,
- def->iothreadids[i]->iothread_id,
- true, &cgroup_iothread) < 0)
- goto cleanup;
-
- if (period || quota) {
- if (qemuSetupCgroupVcpuBW(cgroup_iothread, period, quota) < 0)
- goto cleanup;
- }
-
- /* Set iothreadpin in cgroup if iothreadpin xml is provided */
- if (virCgroupHasController(priv->cgroup,
- VIR_CGROUP_CONTROLLER_CPUSET)) {
- virBitmapPtr cpumask = NULL;
-
- if (mem_mask &&
- virCgroupSetCpusetMems(cgroup_iothread, mem_mask) < 0)
- goto cleanup;
-
- if (def->iothreadids[i]->cpumask)
- cpumask = def->iothreadids[i]->cpumask;
- else if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
- cpumask = priv->autoCpuset;
- else
- cpumask = def->cpumask;
-
- if (cpumask &&
- qemuSetupCgroupCpusetCpus(cgroup_iothread, cpumask) < 0)
- goto cleanup;
- }
-
- /* move the thread for iothread to sub dir */
- if (virCgroupAddTask(cgroup_iothread,
- def->iothreadids[i]->thread_id) < 0)
- goto cleanup;
-
- virCgroupFree(&cgroup_iothread);
- }
- VIR_FREE(mem_mask);
-
- return 0;
-
- cleanup:
- if (cgroup_iothread) {
- virCgroupRemove(cgroup_iothread);
- virCgroupFree(&cgroup_iothread);
- }
- VIR_FREE(mem_mask);
-
- return -1;
-}
int
qemuRemoveCgroup(virDomainObjPtr vm)
return ret;
}
-/* Set CPU affinities for IOThreads threads. */
-static int
-qemuProcessSetIOThreadsAffinity(virDomainObjPtr vm)
-{
- virDomainDefPtr def = vm->def;
- size_t i;
- int ret = -1;
-
- for (i = 0; i < def->niothreadids; i++) {
- /* set affinity only for existing iothreads */
- if (!def->iothreadids[i]->cpumask)
- continue;
-
- if (virProcessSetAffinity(def->iothreadids[i]->thread_id,
- def->iothreadids[i]->cpumask) < 0)
- goto cleanup;
- }
- ret = 0;
-
- cleanup:
- return ret;
-}
-
-static int
-qemuProcessSetSchedulers(virDomainObjPtr vm)
-{
- size_t i = 0;
-
- for (i = 0; i < vm->def->niothreadids; i++) {
- virDomainIOThreadIDDefPtr info = vm->def->iothreadids[i];
-
- if (info->sched.policy == VIR_PROC_POLICY_NONE)
- continue;
-
- if (virProcessSetScheduler(info->thread_id, info->sched.policy,
- info->sched.priority) < 0)
- return -1;
- }
-
- return 0;
-}
static int
qemuProcessInitPasswords(virConnectPtr conn,
}
+/**
+ * qemuProcessSetupIOThread:
+ * @vm: domain object
+ * @iothread: iothread data structure to set the data for
+ *
+ * This function sets resource properities (affinity, cgroups, scheduler) for a
+ * IOThread. This function expects that the IOThread is online and the IOThread
+ * pids were correctly detected at the point when it's called.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+int
+qemuProcessSetupIOThread(virDomainObjPtr vm,
+ virDomainIOThreadIDDefPtr iothread)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ unsigned long long period = vm->def->cputune.period;
+ long long quota = vm->def->cputune.quota;
+ virDomainNumatuneMemMode mem_mode;
+ char *mem_mask = NULL;
+ virCgroupPtr cgroup_iothread = NULL;
+ virBitmapPtr cpumask = NULL;
+ int ret = -1;
+
+ if ((period || quota) &&
+ !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("cgroup cpu is required for scheduler tuning"));
+ return -1;
+ }
+
+ if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU) ||
+ virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
+ if (virDomainNumatuneGetMode(vm->def->numa, -1, &mem_mode) == 0 &&
+ mem_mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
+ virDomainNumatuneMaybeFormatNodeset(vm->def->numa,
+ priv->autoNodeset,
+ &mem_mask, -1) < 0)
+ goto cleanup;
+
+ if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_IOTHREAD,
+ iothread->iothread_id,
+ true, &cgroup_iothread) < 0)
+ goto cleanup;
+ }
+
+ if (iothread->cpumask)
+ cpumask = iothread->cpumask;
+ else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO)
+ cpumask = priv->autoCpuset;
+ else
+ cpumask = vm->def->cpumask;
+
+ if (period || quota) {
+ if (qemuSetupCgroupVcpuBW(cgroup_iothread, period, quota) < 0)
+ goto cleanup;
+ }
+
+ if (cgroup_iothread) {
+ if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
+ if (mem_mask &&
+ virCgroupSetCpusetMems(cgroup_iothread, mem_mask) < 0)
+ goto cleanup;
+
+ if (cpumask &&
+ qemuSetupCgroupCpusetCpus(cgroup_iothread, cpumask) < 0)
+ goto cleanup;
+ }
+
+ if (virCgroupAddTask(cgroup_iothread, iothread->thread_id) < 0)
+ goto cleanup;
+ }
+
+ if (cpumask && virProcessSetAffinity(iothread->thread_id, cpumask) < 0)
+ goto cleanup;
+
+ if (iothread->sched.policy != VIR_PROC_POLICY_NONE &&
+ virProcessSetScheduler(iothread->thread_id, iothread->sched.policy,
+ iothread->sched.priority) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+ cleanup:
+ if (cgroup_iothread) {
+ if (ret < 0)
+ virCgroupRemove(cgroup_iothread);
+ virCgroupFree(&cgroup_iothread);
+ }
+
+ VIR_FREE(mem_mask);
+ return ret;
+}
+
+
+static int
+qemuProcessSetupIOThreads(virDomainObjPtr vm)
+{
+ size_t i;
+
+ for (i = 0; i < vm->def->niothreadids; i++) {
+ virDomainIOThreadIDDefPtr info = vm->def->iothreadids[i];
+
+ if (qemuProcessSetupIOThread(vm, info) < 0)
+ return -1;
+ }
+
+ return 0;
+}
+
+
/**
* qemuProcessLaunch:
*
if (qemuProcessSetupVcpus(vm) < 0)
goto cleanup;
- VIR_DEBUG("Setting cgroup for each IOThread (if required)");
- if (qemuSetupCgroupForIOThreads(vm) < 0)
- goto cleanup;
-
- VIR_DEBUG("Setting affinity of IOThread threads");
- if (qemuProcessSetIOThreadsAffinity(vm) < 0)
- goto cleanup;
-
- VIR_DEBUG("Setting scheduler parameters");
- if (qemuProcessSetSchedulers(vm) < 0)
+ VIR_DEBUG("Setting IOThread tuning/settings");
+ if (qemuProcessSetupIOThreads(vm) < 0)
goto cleanup;
VIR_DEBUG("Setting any required VM passwords");