net/virtio-user: enable multiqueue with kernel vhost
[dpdk.git] / drivers / net / virtio / virtio_user / vhost_kernel_tap.c
index 797713b..f585de8 100644 (file)
 #include "../virtio_logs.h"
 
 int
-vhost_kernel_open_tap(char **p_ifname, int hdr_size)
+vhost_kernel_open_tap(char **p_ifname, int hdr_size, int req_mq)
 {
        unsigned int tap_features;
        int sndbuf = INT_MAX;
        struct ifreq ifr;
        int tapfd;
+       unsigned int offload =
+                       TUN_F_CSUM |
+                       TUN_F_TSO4 |
+                       TUN_F_TSO6 |
+                       TUN_F_TSO_ECN |
+                       TUN_F_UFO;
 
        /* TODO:
         * 1. verify we can get/set vnet_hdr_len, tap_probe_vnet_hdr_len
@@ -85,6 +91,9 @@ vhost_kernel_open_tap(char **p_ifname, int hdr_size)
                goto error;
        }
 
+       if (req_mq)
+               ifr.ifr_flags |= IFF_MULTI_QUEUE;
+
        if (*p_ifname)
                strncpy(ifr.ifr_name, *p_ifname, IFNAMSIZ);
        else
@@ -106,6 +115,14 @@ vhost_kernel_open_tap(char **p_ifname, int hdr_size)
                goto error;
        }
 
+       /* TODO: before set the offload capabilities, we'd better (1) check
+        * negotiated features to see if necessary to offload; (2) query tap
+        * to see if it supports the offload capabilities.
+        */
+       if (ioctl(tapfd, TUNSETOFFLOAD, offload) != 0)
+               PMD_DRV_LOG(ERR, "TUNSETOFFLOAD ioctl() failed: %s",
+                          strerror(errno));
+
        if (!(*p_ifname))
                *p_ifname = strdup(ifr.ifr_name);