Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 5 Aug 2016 14:16:58 GMT
From:      vincenzo@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r307241 - soc2016/vincenzo/head/usr.sbin/bhyve
Message-ID:  <201608051416.u75EGweL022460@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: vincenzo
Date: Fri Aug  5 14:16:58 2016
New Revision: 307241
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=307241

Log:
   bhyve: netmap_recv: write it from scratch

Modified:
  soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c
  soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h
  soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c

Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c
==============================================================================
--- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c	Fri Aug  5 14:16:10 2016	(r307240)
+++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.c	Fri Aug  5 14:16:58 2016	(r307241)
@@ -91,8 +91,7 @@
 	 * times to receive a single packet, depending of how big is
 	 * buffers you provide.
 	 */
-	int (*recv)(struct net_backend *be, struct iovec *iov,
-		    int iovcnt, int *more);
+	int (*recv)(struct net_backend *be, struct iovec *iov, int iovcnt);
 
 	/*
 	 * Ask the backend for the virtio-net features it is able to
@@ -158,8 +157,7 @@
 }
 
 static int
-netbe_null_recv(struct net_backend *be, struct iovec *iov,
-	int iovcnt, int *more)
+netbe_null_recv(struct net_backend *be, struct iovec *iov, int iovcnt)
 {
 	fprintf(stderr, "netbe_null_recv called ?\n");
 	return -1; /* never called, i believe */
@@ -278,13 +276,12 @@
 }
 
 static int
-tap_recv(struct net_backend *be, struct iovec *iov, int iovcnt, int *more)
+tap_recv(struct net_backend *be, struct iovec *iov, int iovcnt)
 {
 	int ret;
 
 	/* Should never be called without a valid tap fd */
 	assert(be->fd != -1);
-	*more = 0;
 
 	ret = readv(be->fd, iov, iovcnt);
 
@@ -739,90 +736,68 @@
 }
 
 static int
-netmap_recv(struct net_backend *be, struct iovec *iov,
-	    int iovcnt, int *more)
+netmap_recv(struct net_backend *be, struct iovec *iov, int iovcnt)
 {
 	struct netmap_priv *priv = be->priv;
+	struct netmap_slot *slot = NULL;
 	struct netmap_ring *ring;
-	int tot = 0;
-	int copylen;
-	int iov_avail;
-	uint8_t *iov_buf;
+	void *iov_frag_buf;
+	int iov_frag_size;
+	int totlen = 0;
+	uint32_t head;
 
 	assert(iovcnt);
 
 	ring = priv->rx;
+	head = ring->head;
+	iov_frag_buf = iov->iov_base;
+	iov_frag_size = iov->iov_len;
 
-	/* Init iovec pointers. */
-	iov_buf = iov->iov_base;
-	iov_avail = iov->iov_len;
-
-	if (!priv->rx_continue) {
-		/* Init netmap pointers. */
-		priv->rx_idx = ring->cur;
-		priv->rx_avail_slots = nm_ring_space(ring);
-		priv->rx_buf = NETMAP_BUF(ring,
-				ring->slot[priv->rx_idx].buf_idx);
-		priv->rx_avail = ring->slot[priv->rx_idx].len;
-		priv->rx_morefrag = (ring->slot[priv->rx_idx].flags
-					& NS_MOREFRAG);
+	do {
+		int nm_buf_len;
+		void *nm_buf;
 
-		if (!priv->rx_avail_slots) {
-			goto out;
+		if (head == ring->tail) {
+			return 0;
 		}
-		priv->rx_continue = 1;
-	}
 
-	for (;;) {
-		copylen = priv->rx_avail;
-		if (copylen > iov_avail) {
-			copylen = iov_avail;
-		}
+		slot = ring->slot + head;
+		nm_buf = NETMAP_BUF(ring, slot->buf_idx);
+		nm_buf_len = slot->len;
+
+		for (;;) {
+			int copylen = nm_buf_len < iov_frag_size ? nm_buf_len : iov_frag_size;
+
+			pkt_copy(nm_buf, iov_frag_buf, copylen);
+			nm_buf += copylen;
+			nm_buf_len -= copylen;
+			iov_frag_buf += copylen;
+			iov_frag_size -= copylen;
+			totlen += copylen;
 
-		/* Copy and update pointers. */
-		bcopy(priv->rx_buf, iov_buf, copylen);
-		iov_buf += copylen;
-		iov_avail -= copylen;
-		priv->rx_buf += copylen;
-		priv->rx_avail -= copylen;
-		tot += copylen;
-
-		if (!priv->rx_avail) {
-			priv->rx_avail_slots--;
-			if (!priv->rx_morefrag || !priv->rx_avail_slots) {
-				priv->rx_continue = 0;
+			if (nm_buf_len == 0) {
 				break;
 			}
-			/* Go to the next netmap slot. */
-			priv->rx_idx = nm_ring_next(ring, priv->rx_idx);
-			priv->rx_buf = NETMAP_BUF(ring,
-					ring->slot[priv->rx_idx].buf_idx);
-			priv->rx_avail = ring->slot[priv->rx_idx].len;
-			priv->rx_morefrag =
-				(ring->slot[priv->rx_idx].flags
-					& NS_MOREFRAG);
-		}
 
-		if (!iov_avail) {
+			iov++;
 			iovcnt--;
-			if (!iovcnt) {
-				break;
+			if (iovcnt == 0) {
+				/* No space to receive. */
+				D("Short iov, drop %d bytes", totlen);
+				return -ENOSPC;
 			}
-			/* Go to the next iovec descriptor. */
-			iov++;
-			iov_buf = iov->iov_base;
-			iov_avail = iov->iov_len;
+			iov_frag_buf = iov->iov_base;
+			iov_frag_size = iov->iov_len;
 		}
-	}
 
-	if (!priv->rx_continue) {
-		/* End of reception: Update the ring now. */
-		ring->cur = ring->head = nm_ring_next(ring, priv->rx_idx);
-	}
-out:
-	*more = priv->rx_continue;
+		head = nm_ring_next(ring, head);
+
+	} while (slot->flags & NS_MOREFRAG);
+
+	/* Release slots to netmap. */
+	ring->head = ring->cur = head;
 
-	return tot;
+	return totlen;
 }
 
 static struct net_backend netmap_backend = {
@@ -1020,7 +995,7 @@
 }
 
 int
-netbe_recv(struct net_backend *be, struct iovec *iov, int iovcnt, int *more)
+netbe_recv(struct net_backend *be, struct iovec *iov, int iovcnt)
 {
 	int hlen = 0;
 	int ret;
@@ -1052,7 +1027,7 @@
 		}
 	}
 
-	ret = be->recv(be, iov, iovcnt, more);
+	ret = be->recv(be, iov, iovcnt);
 	if (ret > 0) {
 		ret += hlen;
 	}

Modified: soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h
==============================================================================
--- soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h	Fri Aug  5 14:16:10 2016	(r307240)
+++ soc2016/vincenzo/head/usr.sbin/bhyve/net_backends.h	Fri Aug  5 14:16:58 2016	(r307241)
@@ -47,8 +47,7 @@
 			    unsigned vnet_hdr_len);
 void	netbe_send(struct net_backend *be, struct iovec *iov,
 		   int iovcnt, int len, int more);
-int	netbe_recv(struct net_backend *be, struct iovec *iov,
-		   int iovcnt, int *more);
+int	netbe_recv(struct net_backend *be, struct iovec *iov, int iovcnt);
 
 
 /*

Modified: soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c
==============================================================================
--- soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c	Fri Aug  5 14:16:10 2016	(r307240)
+++ soc2016/vincenzo/head/usr.sbin/bhyve/pci_virtio_net.c	Fri Aug  5 14:16:58 2016	(r307241)
@@ -209,11 +209,10 @@
 	 * We only make it large enough for TSO-sized segment.
 	 */
 	static uint8_t dummybuf[65536+64];
-	int more;
 
 	iov[0].iov_base = dummybuf;
 	iov[0].iov_len = sizeof(dummybuf);
-	netbe_recv(sc->vsc_be, iov, 1, &more);
+	netbe_recv(sc->vsc_be, iov, 1);
 }
 
 static void
@@ -223,7 +222,6 @@
 	struct vqueue_info *vq;
 	int len, n;
 	uint16_t idx;
-	int more;
 
 	/*
 	 * This will be called when the rx ring hasn't yet
@@ -258,7 +256,7 @@
 		n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL);
 		assert(n >= 1 && n <= VTNET_MAXSEGS);
 
-		len = netbe_recv(sc->vsc_be, iov, n, &more);
+		len = netbe_recv(sc->vsc_be, iov, n);
 
 		if (len == 0) {
 			/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608051416.u75EGweL022460>