]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Enable multiqueue for macvtaps
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 4 Dec 2015 10:47:22 +0000 (11:47 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 11 Dec 2015 07:44:44 +0000 (08:44 +0100)
https://bugzilla.redhat.com/show_bug.cgi?id=1240439

Ta-da! Now that we know how to open a macvtap device multiple
times, we can finally enable the multiqueue feature. Everything
else is already prepared (e.g. command line generation) from the
previous iteration where the feature was implemented for
TUN/TAP devices.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
src/qemu/qemu_command.c
src/qemu/qemu_command.h
src/qemu/qemu_hotplug.c

index d856377489e1737658aa1d218926c91b250993d7..d2f37e408babca97ad14d8d31ddb45d9b6263083 100644 (file)
@@ -212,17 +212,21 @@ qemuVirCommandGetDevSet(virCommandPtr cmd, int fd)
  * @def: the definition of the VM (needed by 802.1Qbh and audit)
  * @driver: pointer to the driver instance
  * @net: pointer to the VM's interface description with direct device type
+ * @tapfd: array of file descriptor return value for the new device
+ * @tapfdSize: number of file descriptors in @tapfd
  * @vmop: VM operation type
  *
- * Returns a filedescriptor on success or -1 in case of error.
+ * Returns 0 on success or -1 in case of error.
  */
 int
 qemuPhysIfaceConnect(virDomainDefPtr def,
                      virQEMUDriverPtr driver,
                      virDomainNetDefPtr net,
+                     int *tapfd,
+                     size_t tapfdSize,
                      virNetDevVPortProfileOp vmop)
 {
-    int rc;
+    int ret = -1;
     char *res_ifname = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     unsigned int macvlan_create_flags = VIR_NETDEV_MACVLAN_CREATE_WITH_TAP;
@@ -238,18 +242,22 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
                                                virDomainNetGetActualVirtPortProfile(net),
                                                &res_ifname,
                                                vmop, cfg->stateDir,
-                                               &rc, 1,
+                                               tapfd, tapfdSize,
                                                macvlan_create_flags) < 0)
-        return -1;
+        goto cleanup;
 
-    if (rc >= 0) {
-        virDomainAuditNetDevice(def, net, res_ifname, true);
-        VIR_FREE(net->ifname);
-        net->ifname = res_ifname;
-    }
+    virDomainAuditNetDevice(def, net, res_ifname, true);
+    VIR_FREE(net->ifname);
+    net->ifname = res_ifname;
+    ret = 0;
 
+ cleanup:
+    if (ret < 0) {
+        while (tapfdSize--)
+            VIR_FORCE_CLOSE(tapfd[tapfdSize]);
+    }
     virObjectUnref(cfg);
-    return rc;
+    return ret;
 }
 
 
@@ -8746,7 +8754,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
     /* Currently nothing besides TAP devices supports multiqueue. */
     if (net->driver.virtio.queues > 0 &&
         !(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
-          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
+          actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+          actualType == VIR_DOMAIN_NET_TYPE_DIRECT)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("Multiqueue network is not supported for: %s"),
                        virDomainNetTypeToString(actualType));
@@ -8791,11 +8800,17 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
                                     tapfd, &tapfdSize) < 0)
             goto cleanup;
     } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
-        if (VIR_ALLOC(tapfd) < 0 || VIR_ALLOC(tapfdName) < 0)
+        tapfdSize = net->driver.virtio.queues;
+        if (!tapfdSize)
+            tapfdSize = 1;
+
+        if (VIR_ALLOC_N(tapfd, tapfdSize) < 0 ||
+            VIR_ALLOC_N(tapfdName, tapfdSize) < 0)
             goto cleanup;
-        tapfdSize = 1;
-        tapfd[0] = qemuPhysIfaceConnect(def, driver, net, vmop);
-        if (tapfd[0] < 0)
+
+        memset(tapfd, -1, tapfdSize * sizeof(tapfd[0]));
+
+        if (qemuPhysIfaceConnect(def, driver, net, tapfd, tapfdSize, vmop) < 0)
             goto cleanup;
     }
 
index bebdd27f98257e80bc601fedec71bb46ea3e22e5..f0d6900b46755e4e20d90470b764d951ea001215 100644 (file)
@@ -232,6 +232,8 @@ int qemuNetworkIfaceConnect(virDomainDefPtr def,
 int qemuPhysIfaceConnect(virDomainDefPtr def,
                          virQEMUDriverPtr driver,
                          virDomainNetDefPtr net,
+                         int *tapfd,
+                         size_t tapfdSize,
                          virNetDevVPortProfileOp vmop);
 
 int qemuOpenVhostNet(virDomainDefPtr def,
index 1a61701c49b6783376da06b405f56c1cf8b81cee..a88c2f2de78fcc5d64187e96d6f1097a9a235fb5 100644 (file)
@@ -951,15 +951,17 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
         if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
             goto cleanup;
     } else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
-        tapfdSize = vhostfdSize = 1;
-        if (VIR_ALLOC(tapfd) < 0)
+        tapfdSize = vhostfdSize = net->driver.virtio.queues;
+        if (!tapfdSize)
+            tapfdSize = vhostfdSize = 1;
+        if (VIR_ALLOC_N(tapfd, tapfdSize) < 0)
             goto cleanup;
-        *tapfd = -1;
-        if (VIR_ALLOC(vhostfd) < 0)
+        memset(tapfd, -1, sizeof(*tapfd) * tapfdSize);
+        if (VIR_ALLOC_N(vhostfd, vhostfdSize) < 0)
             goto cleanup;
-        *vhostfd = -1;
-        if ((tapfd[0] = qemuPhysIfaceConnect(vm->def, driver, net,
-                                             VIR_NETDEV_VPORT_PROFILE_OP_CREATE)) < 0)
+        memset(vhostfd, -1, sizeof(*vhostfd) * vhostfdSize);
+        if (qemuPhysIfaceConnect(vm->def, driver, net, tapfd, tapfdSize,
+                                 VIR_NETDEV_VPORT_PROFILE_OP_CREATE) < 0)
             goto cleanup;
         iface_connected = true;
         if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)