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
# 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. */
# 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);
}
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"