net/virtio: support NAPI when using vhost-net backend
authorHarold Huang <baymaxhuang@gmail.com>
Wed, 2 Mar 2022 09:41:05 +0000 (17:41 +0800)
committerMaxime Coquelin <maxime.coquelin@redhat.com>
Mon, 9 May 2022 19:15:38 +0000 (21:15 +0200)
In patch [1], NAPI has been supported in kernel tun driver to accelerate
packet processing received from vhost-net. This will greatly improve the
throughput of the tap device in the vhost-net backend.

[1]: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=fb3f903769e8

Signed-off-by: Harold Huang <baymaxhuang@gmail.com>
Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
drivers/net/virtio/virtio_user/vhost_kernel.c
drivers/net/virtio/virtio_user/vhost_kernel_tap.c
drivers/net/virtio/virtio_user/vhost_kernel_tap.h

index 202a8cd..986b56a 100644 (file)
@@ -383,6 +383,7 @@ vhost_kernel_setup(struct virtio_user_dev *dev)
        struct vhost_kernel_data *data;
        unsigned int tap_features;
        unsigned int tap_flags;
+       unsigned int r_flags;
        const char *ifname;
        uint32_t q, i;
        int vhostfd;
@@ -394,6 +395,10 @@ vhost_kernel_setup(struct virtio_user_dev *dev)
                PMD_INIT_LOG(ERR, "TAP does not support IFF_VNET_HDR");
                return -1;
        }
+       r_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
+
+       if (tap_features & IFF_NAPI)
+               r_flags |= IFF_NAPI;
 
        data = malloc(sizeof(*data));
        if (!data) {
@@ -429,7 +434,7 @@ vhost_kernel_setup(struct virtio_user_dev *dev)
        }
 
        ifname = dev->ifname != NULL ? dev->ifname : "tap%d";
-       data->tapfds[0] = tap_open(ifname, (tap_features & IFF_MULTI_QUEUE) != 0);
+       data->tapfds[0] = tap_open(ifname, r_flags, (tap_features & IFF_MULTI_QUEUE) != 0);
        if (data->tapfds[0] < 0)
                goto err_tapfds;
        if (dev->ifname == NULL && tap_get_name(data->tapfds[0], &dev->ifname) < 0) {
@@ -446,7 +451,7 @@ vhost_kernel_setup(struct virtio_user_dev *dev)
        }
 
        for (i = 1; i < dev->max_queue_pairs; i++) {
-               data->tapfds[i] = tap_open(dev->ifname, true);
+               data->tapfds[i] = tap_open(dev->ifname, r_flags, true);
                if (data->tapfds[i] < 0)
                        goto err_tapfds;
        }
index 2aac402..611e2e2 100644 (file)
@@ -42,7 +42,7 @@ tap_support_features(unsigned int *tap_features)
 }
 
 int
-tap_open(const char *ifname, bool multi_queue)
+tap_open(const char *ifname, unsigned int r_flags, bool multi_queue)
 {
        struct ifreq ifr;
        int tapfd;
@@ -61,7 +61,7 @@ tap_open(const char *ifname, bool multi_queue)
 retry_mono_q:
        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, ifname, IFNAMSIZ - 1);
-       ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
+       ifr.ifr_flags = r_flags;
        if (multi_queue)
                ifr.ifr_flags |= IFF_MULTI_QUEUE;
        if (ioctl(tapfd, TUNSETIFF, (void *)&ifr) == -1) {
index 726433c..636a048 100644 (file)
@@ -22,6 +22,7 @@
 #define IFF_NO_PI        0x1000
 #define IFF_VNET_HDR     0x4000
 #define IFF_MULTI_QUEUE  0x0100
+#define IFF_NAPI         0x0010
 
 /* Features for GSO (TUNSETOFFLOAD). */
 #define TUN_F_CSUM     0x01    /* You can hand me unchecksummed packets. */
@@ -36,7 +37,7 @@
 int vhost_kernel_tap_setup(int tapfd, int hdr_size, uint64_t features);
 
 int tap_support_features(unsigned int *tap_features);
-int tap_open(const char *ifname, bool multi_queue);
+int tap_open(const char *ifname, unsigned int r_flags, bool multi_queue);
 int tap_get_name(int tapfd, char **ifname);
 int tap_get_flags(int tapfd, unsigned int *tap_flags);
 int tap_set_mac(int tapfd, uint8_t *mac);