diff --git a/LINUX/final-patches/vanilla--virtio_net.c--50b00--99999 b/LINUX/final-patches/vanilla--virtio_net.c--50b00--60500 similarity index 100% rename from LINUX/final-patches/vanilla--virtio_net.c--50b00--99999 rename to LINUX/final-patches/vanilla--virtio_net.c--50b00--60500 diff --git a/LINUX/final-patches/vanilla--virtio_net.c--60500--99999 b/LINUX/final-patches/vanilla--virtio_net.c--60500--99999 new file mode 100644 index 000000000..4cdce8046 --- /dev/null +++ b/LINUX/final-patches/vanilla--virtio_net.c--60500--99999 @@ -0,0 +1,100 @@ +diff --git a/virtio_net.c b/virtio_net.c +index 8e9f4cfe941f..a4eae7a07304 100644 +--- a/virtio_net.c ++++ b/virtio_net.c +@@ -293,6 +293,10 @@ struct virtnet_info { + struct failover *failover; + }; + ++#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) ++#include ++#endif ++ + struct padded_vnet_hdr { + struct virtio_net_hdr_v1_hash hdr; + /* +@@ -421,6 +425,11 @@ static void skb_xmit_done(struct virtqueue *vq) + /* Suppress further interrupts. */ + virtqueue_disable_cb(vq); + ++#ifdef DEV_NETMAP ++ if (netmap_tx_irq(vi->dev, vq2txq(vq))) ++ return; ++#endif ++ + if (napi->weight) + virtqueue_napi_schedule(napi, vq); + else +@@ -1955,6 +1964,18 @@ static int virtnet_poll(struct napi_struct *napi, int budget) + unsigned int received; + unsigned int xdp_xmit = 0; + ++#ifdef DEV_NETMAP ++ int work_done = 0; ++ int nm_irq = netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done); ++ ++ if (nm_irq == NM_IRQ_COMPLETED) { ++ napi_complete(napi); ++ return 1; ++ } else if (nm_irq == NM_IRQ_RESCHED) { ++ return budget; ++ } ++#endif ++ + virtnet_poll_cleantx(rq); + + received = virtnet_receive(rq, budget, &xdp_xmit); +@@ -2015,6 +2036,15 @@ static int virtnet_open(struct net_device *dev) + { + struct virtnet_info *vi = netdev_priv(dev); + int i, err; ++#ifdef DEV_NETMAP ++ int ok = virtio_netmap_init_buffers(vi); ++ ++ if (ok) { ++ for (i = 0; i < vi->max_queue_pairs; i++) ++ virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi); ++ return 0; ++ } ++#endif + + enable_delayed_refill(vi); + +@@ -4259,6 +4289,12 @@ static int virtnet_probe(struct virtio_device *vdev) + goto free_unregister_netdev; + } + ++ virtnet_set_queues(vi, vi->curr_queue_pairs); ++ ++#ifdef DEV_NETMAP ++ virtio_netmap_attach(vi); ++#endif ++ + /* Assume link up if device can't report link status, + otherwise get link status from config. */ + netif_carrier_off(dev); +@@ -4311,7 +4347,14 @@ static void remove_vq_common(struct virtnet_info *vi) + static void virtnet_remove(struct virtio_device *vdev) + { + struct virtnet_info *vi = vdev->priv; ++#ifdef DEV_NETMAP ++ /* Save the pointer, will go away after netmap_detach(). */ ++ struct netmap_adapter *token = NA(vi->dev); + ++ netmap_detach(vi->dev); ++ virtio_netmap_clean_used_rings(vi, token); ++ virtio_netmap_reclaim_unused(vi); ++#endif + virtnet_cpu_notif_remove(vi); + + /* Make sure no work handler is accessing the device. */ +@@ -4386,6 +4429,9 @@ static unsigned int features_legacy[] = { + VIRTNET_FEATURES, + VIRTIO_NET_F_GSO, + VIRTIO_F_ANY_LAYOUT, ++#ifdef VIRTIO_NET_F_PTNETMAP ++ VIRTIO_NET_F_PTNETMAP, ++#endif + }; + + static struct virtio_driver virtio_net_driver = {