Date: Fri, 21 Nov 2014 22:06:13 +0000 (UTC) From: eclectic 923 <eclectic923@yahoo.com> To: "net@freebsd.org" <net@freebsd.org> Subject: Patches for linux virtio_net driver Message-ID: <1960028583.3815364.1416607573474.JavaMail.yahoo@jws10669.mail.bf1.yahoo.com>
index | next in thread | raw e-mail
[-- Attachment #1 --] I know this is the Freebsd mailing list, but http://info.iet.unipi.it/~luigi/netmap/#85cb indicates that discussion should be sent to this list. I recently added netmap to a 3.10 LINUX kernel for use in a KVM guest. The virtio driver didn't work. There were two problems. On the 3.10.60 kernel from kernel.org, the patch to virtio_net.c didn't work, one part of the patch was rejected. This is easily fixed. More serious, was that the virtio initialization code didn't work, nor did the packet receive code. The basic problem was failure to initialize the indices properly and failure to maintain a 1 slot separation between head/tail indices. (Same problem 2 locations in the code.) This problem is easily seen by creating a KVM guest with a netmap/virtio_net driver, and simply pinging the guest from the host. The receive traffic can easily be monitored using the pkt-gen tool on the guest. The first 255 pings will work fine, when the index hits 255, then the packet receive will fail, and will continue to fail every time on slot 255. I've included patches for both problems in the hopes that the source code will be updated and others won't have to find these problems. If the source code won't be updated, then I'd appreciate suggestions on the best place to post these patches so others can find them. -- Joe Garvey [-- Attachment #2 --] # The netmap 3.10 patch for the virtio_net driver fails to apply. This # patch is the whole netmap virtio driver patch for 3.10.60 (from # kernel.org), and it applies correctly. # Index: linux-3.10.60/drivers/net/virtio_net.c =================================================================== --- linux-3.10.60.orig/drivers/net/virtio_net.c 2014-11-14 11:48:23.000000000 -0500 +++ linux-3.10.60/drivers/net/virtio_net.c 2014-11-21 12:54:29.751760095 -0500 @@ -131,6 +131,10 @@ struct notifier_block nb; }; +#if defined(CONFIG_NETMAP) || defined(CONFIG_NETMAP_MODULE) +#include <virtio_netmap.h> +#endif + struct skb_vnet_hdr { union { struct virtio_net_hdr hdr; @@ -210,6 +214,10 @@ /* Suppress further interrupts. */ virtqueue_disable_cb(vq); +#ifdef DEV_NETMAP + if (netmap_tx_irq(vi->dev, vq2txq(vq))) + return; +#endif /* We were probably waiting for more output buffers. */ netif_wake_subqueue(vi->dev, vq2txq(vq)); } @@ -646,7 +654,16 @@ struct virtnet_info *vi = rq->vq->vdev->priv; void *buf; unsigned int r, len, received = 0; +#ifdef DEV_NETMAP + int work_done = 0; + + if (netmap_rx_irq(vi->dev, vq2rxq(rq->vq), &work_done)) { + napi_complete(napi); + ND("called netmap_rx_irq"); + return 1; + } +#endif again: while (received < budget && (buf = virtqueue_get_buf(rq->vq, &len)) != NULL) { @@ -679,6 +696,16 @@ { struct virtnet_info *vi = netdev_priv(dev); int i; +#ifdef DEV_NETMAP + int ok = virtio_netmap_init_buffers(vi); + + netmap_enable_all_rings(dev); + if (ok) { + for (i = 0; i < vi->max_queue_pairs; i++) + virtnet_napi_enable(&vi->rq[i]); + return 0; + } +#endif for (i = 0; i < vi->max_queue_pairs; i++) { if (i < vi->curr_queue_pairs) @@ -972,6 +999,9 @@ struct virtnet_info *vi = netdev_priv(dev); int i; +#ifdef DEV_NETMAP + netmap_disable_all_rings(dev); +#endif /* Make sure refill_work doesn't re-enable napi! */ cancel_delayed_work_sync(&vi->refill); @@ -1644,6 +1674,10 @@ goto free_recv_bufs; } +#ifdef DEV_NETMAP + virtio_netmap_attach(vi); +#endif + /* Assume link up if device can't report link status, otherwise get link status from config. */ if (virtio_has_feature(vi->vdev, VIRTIO_NET_F_STATUS)) { @@ -1690,6 +1724,9 @@ { struct virtnet_info *vi = vdev->priv; +#ifdef DEV_NETMAP + netmap_detach(vi->dev); +#endif unregister_hotcpu_notifier(&vi->nb); /* Prevent config work handler from accessing the device. */ [-- Attachment #3 --] # This file is a patch to the netmap virtio_net driver include file. # There is a problem with the initialization, and during read packet with # control of the indicies . # # This problem is easily seen by building a KVM netmap/virtio_net driver, and # simply pinging it (host pings KVM guest). All goes well, until ring buffer # reaches index 255, and no packet is actually received. This will fix that # problem and resulted in a working driver. # Index: b/LINUX/virtio_netmap.h =================================================================== --- a/LINUX/virtio_netmap.h 2014-11-21 16:26:03.951278021 -0500 +++ b/LINUX/virtio_netmap.h 2014-11-21 16:26:25.451386665 -0500 @@ -398,8 +398,8 @@ * Second part: skip past packets that userspace has released. */ nm_i = kring->nr_hwcur; /* netmap ring index */ - if (nm_i != head) { - for (n = 0; nm_i != head; n++) { + if (nm_next(nm_i, lim) != head) { + for (n = 0; nm_next(nm_i, lim) != head; n++) { struct netmap_slot *slot = &ring->slot[nm_i]; void *addr = NMB(slot); int err; @@ -421,7 +421,7 @@ virtqueue_kick(vq); nm_i = nm_next(nm_i, lim); } - kring->nr_hwcur = head; + kring->nr_hwcur = nm_i; } /* We have finished processing used RX buffers, so we have to tell @@ -454,6 +454,7 @@ for (r = 0; r < na->num_rx_rings; r++) { COMPAT_DECL_SG struct netmap_ring *ring = na->rx_rings[r].ring; + struct netmap_kring *kring = &na->rx_rings[r]; struct virtqueue *vq = GET_RX_VQ(vi, r); struct scatterlist *sg = GET_RX_SG(vi, r); struct netmap_slot* slot; @@ -485,6 +486,7 @@ if (VQ_FULL(vq, err)) break; } + kring->nr_hwcur = i; D("added %d inbufs on queue %d", i, r); virtqueue_kick(vq); }help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1960028583.3815364.1416607573474.JavaMail.yahoo>
