]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Initialize cpuset for hotplugged vcpu as def->cpuset
authorOsier Yang <jyang@redhat.com>
Fri, 12 Oct 2012 09:50:47 +0000 (17:50 +0800)
committerOsier Yang <jyang@redhat.com>
Mon, 15 Oct 2012 04:16:02 +0000 (12:16 +0800)
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
src/conf/domain_conf.h
src/libvirt_private.syms
src/qemu/qemu_driver.c

index d4a5023c7a54d8e79fd0b67545e6300de035ab52..e90bcc011fd8652c139dc95f9a5b1151fab0939e 100644 (file)
@@ -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)
index cc63da1d009549641f160607d94d2d50d6281a53..5ca1820fdd83a641a3add07f1e5204529d43c0e4 100644 (file)
@@ -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 */
index fe31bbea4ffb7249dc9ffa8b640f09d24d62e9c7..6ea1308e3dbb43ba26716c2377a7166d921d66b2 100644 (file)
@@ -423,6 +423,7 @@ virDomainLiveConfigHelperMethod;
 virDomainLoadAllConfigs;
 virDomainLockFailureTypeFromString;
 virDomainLockFailureTypeToString;
+virDomainLookupVcpuPin;
 virDomainMemballoonModelTypeFromString;
 virDomainMemballoonModelTypeToString;
 virDomainMemDumpTypeFromString;
index 6622a359aeef7b3cc9f5ae5d0db09dc1e99965fb..b3e84247188303043fc8c4d9b002f3dfa5e8656f 100644 (file)
@@ -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;