]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Pin the emulator when only cpuset is specified
authorMartin Kletzander <mkletzan@redhat.com>
Wed, 17 Oct 2012 14:39:31 +0000 (16:39 +0200)
committerMartin Kletzander <mkletzan@redhat.com>
Wed, 17 Oct 2012 15:37:10 +0000 (17:37 +0200)
According to our recent changes (clarifications), we should be pinning
qemu's emulator processes using the <vcpu> 'cpuset' attribute in case
there is no <emulatorpin> specified.  This however doesn't work
entirely as expected and this patch should resolve all the remaining
issues.

src/qemu/qemu_cgroup.c
src/qemu/qemu_cgroup.h
src/qemu/qemu_driver.c
src/qemu/qemu_process.c

index 166f9b97b7845ecea680eecb209272548a864e6e..6b94686a79f1bc7b53fda77fbe3ef727ce3b4a00 100644 (file)
@@ -501,7 +501,7 @@ int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup,
 
     for (i = 0; i < nvcpupin; i++) {
         if (vcpuid == vcpupin[i]->vcpuid) {
-            return qemuSetupCgroupEmulatorPin(cgroup, vcpupin[i]);
+            return qemuSetupCgroupEmulatorPin(cgroup, vcpupin[i]->cpumask);
         }
     }
 
@@ -509,12 +509,12 @@ int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup,
 }
 
 int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup,
-                               virDomainVcpuPinDefPtr vcpupin)
+                               virBitmapPtr cpumask)
 {
     int rc = 0;
     char *new_cpus = NULL;
 
-    new_cpus = virBitmapFormat(vcpupin->cpumask);
+    new_cpus = virBitmapFormat(cpumask);
     if (!new_cpus) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("failed to convert cpu mask"));
@@ -643,6 +643,7 @@ cleanup:
 int qemuSetupCgroupForEmulator(struct qemud_driver *driver,
                                virDomainObjPtr vm)
 {
+    virBitmapPtr cpumask = NULL;
     virCgroupPtr cgroup = NULL;
     virCgroupPtr cgroup_emulator = NULL;
     virDomainDefPtr def = vm->def;
@@ -690,12 +691,18 @@ int qemuSetupCgroupForEmulator(struct qemud_driver *driver,
         }
     }
 
-    if (def->cputune.emulatorpin &&
-        qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
-        rc = qemuSetupCgroupEmulatorPin(cgroup_emulator,
-                                        def->cputune.emulatorpin);
-        if (rc < 0)
-            goto cleanup;
+    if (def->cputune.emulatorpin)
+        cpumask = def->cputune.emulatorpin->cpumask;
+    else if (def->cpumask)
+        cpumask = def->cpumask;
+
+    if (cpumask) {
+        if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) {
+            rc = qemuSetupCgroupEmulatorPin(cgroup_emulator, cpumask);
+            if (rc < 0)
+                goto cleanup;
+        }
+        cpumask = NULL; /* sanity */
     }
 
     if (period || quota) {
index b7b021189e2bc17f7b0eff31979224ff100f8b42..362080aa26745698624ac25ae259552cab803daf 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * qemu_cgroup.h: QEMU cgroup management
  *
- * Copyright (C) 2006-2007, 2009-2011 Red Hat, Inc.
+ * Copyright (C) 2006-2007, 2009-2012 Red Hat, Inc.
  * Copyright (C) 2006 Daniel P. Berrange
  *
  * This library is free software; you can redistribute it and/or
@@ -57,7 +57,7 @@ int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup,
                            virDomainVcpuPinDefPtr *vcpupin,
                            int nvcpupin,
                            int vcpuid);
-int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup, virDomainVcpuPinDefPtr vcpupin);
+int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup, virBitmapPtr cpumask);
 int qemuSetupCgroupForVcpu(struct qemud_driver *driver, virDomainObjPtr vm);
 int qemuSetupCgroupForEmulator(struct qemud_driver *driver,
                                virDomainObjPtr vm);
index fa37bfd3cb94a444c82eaec866cbbfc56a932076..adfbfa6acf0d3d3fb776a8feca407f1baf341c48 100644 (file)
@@ -4245,7 +4245,8 @@ qemudDomainPinEmulator(virDomainPtr dom,
                 if (virCgroupForDomain(driver->cgroup, vm->def->name,
                                        &cgroup_dom, 0) == 0) {
                     if (virCgroupForEmulator(cgroup_dom, &cgroup_emulator, 0) == 0) {
-                        if (qemuSetupCgroupEmulatorPin(cgroup_emulator, newVcpuPin[0]) < 0) {
+                        if (qemuSetupCgroupEmulatorPin(cgroup_emulator,
+                                                       newVcpuPin[0]->cpumask) < 0) {
                             virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                                            _("failed to set cpuset.cpus in cgroup"
                                              " for emulator threads"));
index a94e9c4a36642da07d3b97426bc0aa16db8e1157..e08ec6757f5102d84f1b010f6df8f19381ad5134 100644 (file)
@@ -2024,11 +2024,12 @@ cleanup:
     return ret;
 }
 
-/* Set CPU affinities for emulator threads if emulatorpin xml provided. */
+/* Set CPU affinities for emulator threads. */
 static int
 qemuProcessSetEmulatorAffinites(virConnectPtr conn,
                                 virDomainObjPtr vm)
 {
+    virBitmapPtr cpumask;
     virDomainDefPtr def = vm->def;
     virNodeInfo nodeinfo;
     int ret = -1;
@@ -2036,15 +2037,14 @@ qemuProcessSetEmulatorAffinites(virConnectPtr conn,
     if (virNodeGetInfo(conn, &nodeinfo) != 0)
         return -1;
 
-    if (!def->cputune.emulatorpin)
-        return 0;
-
-    if (virProcessInfoSetAffinity(vm->pid,
-                                  def->cputune.emulatorpin->cpumask) < 0) {
+    if (def->cputune.emulatorpin)
+        cpumask = def->cputune.emulatorpin->cpumask;
+    else if (def->cpumask)
+        cpumask = def->cpumask;
+    else
         goto cleanup;
-    }
 
-    ret = 0;
+    ret = virProcessInfoSetAffinity(vm->pid, cpumask);
 cleanup:
     return ret;
 }