diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 935517fb7f..8cf45dad41 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -343,6 +343,21 @@ int qemuSetupCgroup(struct qemud_driver *driver, vm->def->name); } + if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { + if (vm->def->cputune.shares != 0) { + rc = virCgroupSetCpuShares(cgroup, vm->def->cputune.shares); + if(rc != 0) { + virReportSystemError(-rc, + _("Unable to set io cpu shares for domain %s"), + vm->def->name); + goto cleanup; + } + } + } else { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("CPU tuning is not available on this host")); + } + done: virCgroupFree(&cgroup); return 0; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 539b5ad9a0..104e92d524 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2679,6 +2679,13 @@ qemudDomainPinVcpu(virDomainPtr dom, "%s", _("cpu affinity is not supported")); goto cleanup; } + + if (virDomainVcpupinAdd(vm->def, cpumap, maplen, vcpu) < 0) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("failed to update or add vcpupin xml")); + goto cleanup; + } + ret = 0; cleanup: @@ -4644,6 +4651,8 @@ static int qemuSetSchedulerParameters(virDomainPtr dom, _("unable to set cpu shares tunable")); goto cleanup; } + + vm->def->cputune.shares = params[i].value.ul; } else { qemuReportError(VIR_ERR_INVALID_ARG, _("Invalid parameter `%s'"), param->field); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 209c8cfb4d..e31e1b4bec 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1143,6 +1143,77 @@ qemuProcessInitCpuAffinity(virDomainObjPtr vm) return 0; } +/* Set CPU affinites for vcpus if vcpupin xml provided. */ +static int +qemuProcessSetVcpuAffinites(virConnectPtr conn, + virDomainObjPtr vm) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + virDomainDefPtr def = vm->def; + virNodeInfo nodeinfo; + pid_t vcpupid; + unsigned char *cpumask; + int vcpu, cpumaplen, hostcpus, maxcpu; + + if (virNodeGetInfo(conn, &nodeinfo) != 0) { + return -1; + } + + if (!def->cputune.nvcpupin) + return 0; + + if (priv->vcpupids == NULL) { + qemuReportError(VIR_ERR_NO_SUPPORT, + "%s", _("cpu affinity is not supported")); + return -1; + } + + hostcpus = VIR_NODEINFO_MAXCPUS(nodeinfo); + cpumaplen = VIR_CPU_MAPLEN(hostcpus); + maxcpu = cpumaplen * 8; + + if (maxcpu > hostcpus) + maxcpu = hostcpus; + + for (vcpu = 0; vcpu < def->cputune.nvcpupin; vcpu++) { + if (vcpu != def->cputune.vcpupin[vcpu]->vcpuid) + continue; + + int i; + unsigned char *cpumap = NULL; + + if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) { + virReportOOMError(); + return -1; + } + + cpumask = (unsigned char *)def->cputune.vcpupin[vcpu]->cpumask; + vcpupid = priv->vcpupids[vcpu]; + + /* Convert cpumask to bitmap here. */ + for (i = 0; i < VIR_DOMAIN_CPUMASK_LEN; i++) { + int cur = 0; + int mod = 0; + + if (i) { + cur = i / 8; + mod = i % 8; + } + + if (cpumask[i]) + cpumap[cur] |= 1 << mod; + } + + if (virProcessInfoSetAffinity(vcpupid, + cpumap, + cpumaplen, + maxcpu) < 0) { + return -1; + } + } + + return 0; +} static int qemuProcessInitPasswords(virConnectPtr conn, @@ -2217,6 +2288,10 @@ int qemuProcessStart(virConnectPtr conn, if (qemuProcessDetectVcpuPIDs(driver, vm) < 0) goto cleanup; + VIR_DEBUG0("Setting VCPU affinities"); + if (qemuProcessSetVcpuAffinites(conn, vm) < 0) + goto cleanup; + VIR_DEBUG0("Setting any required VM passwords"); if (qemuProcessInitPasswords(conn, driver, vm, qemuCaps) < 0) goto cleanup;