The onlined vcpu pinning policy should inherit def->cpuset if
it's not specified explicitly, and the affinity should be set
in this case. Oppositely, the offlined vcpu pinning policy should
be free()'ed.
---
src/conf/domain_conf.c | 21 +++++++++++++
src/conf/domain_conf.h | 3 ++
src/libvirt_private.syms | 1 +
src/qemu/qemu_driver.c | 75 ++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 91 insertions(+), 9 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e404a68..17254e3 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8398,6 +8398,27 @@ error:
goto cleanup;
}
+/*
+ * Return the vcpupin related with the vcpu id on SUCCESS, or
+ * NULL on failure.
+ */
+virDomainVcpuPinDefPtr
+virDomainLookupVcpuPin(virDomainDefPtr def,
+ int vcpuid)
+{
+ int i;
+
+ if (!def->cputune.vcpupin)
+ return NULL;
+
+ for (i = 0; i < def->cputune.nvcpupin; i++) {
+ if (def->cputune.vcpupin[i]->vcpuid == vcpuid)
+ return def->cputune.vcpupin[i];
+ }
+
+ return NULL;
+}
+
static int virDomainDefMaybeAddController(virDomainDefPtr def,
int type,
int idx)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index cc63da1..5ca1820 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2302,4 +2302,7 @@ virDomainNetDefPtr virDomainNetFind(virDomainDefPtr def,
int virDomainList(virConnectPtr conn, virHashTablePtr domobjs,
virDomainPtr **domains, unsigned int flags);
+virDomainVcpuPinDefPtr virDomainLookupVcpuPin(virDomainDefPtr def,
+ int vcpuid);
+
#endif /* __DOMAIN_CONF_H */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index fe31bbe..6ea1308 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -423,6 +423,7 @@ virDomainLiveConfigHelperMethod;
virDomainLoadAllConfigs;
virDomainLockFailureTypeFromString;
virDomainLockFailureTypeToString;
+virDomainLookupVcpuPin;
virDomainMemballoonModelTypeFromString;
virDomainMemballoonModelTypeToString;
virDomainMemDumpTypeFromString;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6622a35..b3e8424 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3603,6 +3603,7 @@ static int qemudDomainHotplugVcpus(struct qemud_driver *driver,
int ncpupids;
virCgroupPtr cgroup = NULL;
virCgroupPtr cgroup_vcpu = NULL;
+ bool cgroup_available = false;
qemuDomainObjEnterMonitor(driver, vm);
@@ -3656,11 +3657,13 @@ static int qemudDomainHotplugVcpus(struct qemud_driver *driver,
goto cleanup;
}
- if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) == 0)
{
- int rv = -1;
+ cgroup_available = (virCgroupForDomain(driver->cgroup, vm->def->name,
+ &cgroup, 0) == 0);
- if (nvcpus > oldvcpus) {
- for (i = oldvcpus; i < nvcpus; i++) {
+ if (nvcpus > oldvcpus) {
+ for (i = oldvcpus; i < nvcpus; i++) {
+ if (cgroup_available) {
+ int rv = -1;
/* Create cgroup for the onlined vcpu */
rv = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 1);
if (rv < 0) {
@@ -3680,11 +3683,62 @@ static int qemudDomainHotplugVcpus(struct qemud_driver *driver,
virCgroupRemove(cgroup_vcpu);
goto cleanup;
}
+ }
- virCgroupFree(&cgroup_vcpu);
+ /* Inherit def->cpuset */
+ if (vm->def->cpumask) {
+ /* vm->def->cputune.vcpupin can't be NULL if
+ * vm->def->cpumask is not NULL.
+ */
+ virDomainVcpuPinDefPtr vcpupin = NULL;
+
+ if (VIR_REALLOC_N(vm->def->cputune.vcpupin,
+ vm->def->cputune.nvcpupin + 1) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC(vcpupin) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ vcpupin->cpumask = virBitmapNew(VIR_DOMAIN_CPUMASK_LEN);
+ virBitmapCopy(vcpupin->cpumask, vm->def->cpumask);
+ vcpupin->vcpuid = i;
+ vm->def->cputune.vcpupin[vm->def->cputune.nvcpupin++] =
vcpupin;
+
+ if (cgroup_available) {
+ if (qemuSetupCgroupVcpuPin(cgroup_vcpu,
+ vm->def->cputune.vcpupin,
+ vm->def->cputune.nvcpupin, i) <
0) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("failed to set cpuset.cpus in cgroup"
+ " for vcpu %d"), i);
+ ret = -1;
+ goto cleanup;
+ }
+ } else {
+ if (virProcessInfoSetAffinity(cpupids[i],
+ vcpupin->cpumask) < 0) {
+ virReportError(VIR_ERR_SYSTEM_ERROR,
+ _("failed to set cpu affinity for vcpu
%d"),
+ i);
+ ret = -1;
+ goto cleanup;
+ }
+ }
}
- } else {
- for (i = oldvcpus - 1; i >= nvcpus; i--) {
+
+ virCgroupFree(&cgroup_vcpu);
+ }
+ } else {
+ for (i = oldvcpus - 1; i >= nvcpus; i--) {
+ virDomainVcpuPinDefPtr vcpupin = NULL;
+
+ if (cgroup_available) {
+ int rv = -1;
+
rv = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 0);
if (rv < 0) {
virReportSystemError(-rv,
@@ -3698,9 +3752,12 @@ static int qemudDomainHotplugVcpus(struct qemud_driver *driver,
virCgroupRemove(cgroup_vcpu);
virCgroupFree(&cgroup_vcpu);
}
- }
- virCgroupFree(&cgroup);
+ /* Free vcpupin setting */
+ if ((vcpupin = virDomainLookupVcpuPin(vm->def, i))) {
+ VIR_FREE(vcpupin);
+ }
+ }
}
priv->nvcpupids = ncpupids;
--
1.7.7.6