Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Jun 2016 09:33:18 GMT
From:      vincenzo@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r305574 - soc2016/vincenzo/head/sys/dev/netmap
Message-ID:  <201606270933.u5R9XILq025874@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: vincenzo
Date: Mon Jun 27 09:33:17 2016
New Revision: 305574
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=305574

Log:
   freebsd: ptnet_transmit: handle multiple mbufs

Modified:
  soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c

Modified: soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c
==============================================================================
--- soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c	Mon Jun 27 09:33:05 2016	(r305573)
+++ soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c	Mon Jun 27 09:33:17 2016	(r305574)
@@ -793,6 +793,7 @@
 	struct netmap_ring *ring;
 	struct netmap_slot *slot;
 	struct ptnet_queue *pq;
+	unsigned int prev_head;
 	unsigned int head;
 	unsigned int lim;
 	struct mbuf *mf;
@@ -839,75 +840,88 @@
 	nmbuf = NMB(na, slot);
 	nmbuf_bytes = 0;
 
-	m = drbr_peek(ifp, pq->bufring);
-	if (!m) {
-		device_printf(sc->dev, "%s: Empty drbr\n", __func__);
-		goto out;
-	}
+	while (head != ring->tail) {
+		m = drbr_peek(ifp, pq->bufring);
+		if (!m) {
+			break;
+		}
 
-	if (head == ring->tail) {
-		device_printf(sc->dev, "%s: Drop, no free slots\n", __func__);
-		drbr_putback(ifp, pq->bufring, m);
-		ptring->guest_need_kick = 1;
-		goto out;
-	}
+		for (prev_head = head, mf = m; mf; mf = mf->m_next) {
+			uint8_t *mdata = mf->m_data;
+			int mlen = mf->m_len;
 
-	drbr_advance(ifp, pq->bufring);
+			for (;;) {
+				int copy = NETMAP_BUF_SIZE(na) - nmbuf_bytes;
 
-	for (mf = m; mf; mf = mf->m_next) {
-		uint8_t *mdata = mf->m_data;
-		int mlen = mf->m_len;
+				if (mlen < copy) {
+					copy = mlen;
+				}
+				memcpy(nmbuf, mdata, copy);
 
-		for (;;) {
-			int copy = NETMAP_BUF_SIZE(na) - nmbuf_bytes;
+				mdata += copy;
+				mlen -= copy;
+				nmbuf += copy;
+				nmbuf_bytes += copy;
 
-			if (mlen < copy) {
-				copy = mlen;
-			}
-			memcpy(nmbuf, mdata, copy);
+				if (!mlen) {
+					break;
+				}
 
-			mdata += copy;
-			mlen -= copy;
-			nmbuf += copy;
-			nmbuf_bytes += copy;
+				slot->len = nmbuf_bytes;
+				slot->flags = NS_MOREFRAG;
 
-			if (!mlen) {
-				break;
+				head = nm_next(head, lim);
+				if (head == ring->tail) {
+					/* Run out of slots while processing
+					 * a packet. Reset head to the previous
+					 * position and requeue the mbuf. */
+					device_printf(sc->dev, "%s: Drop, "
+						      " no free slots\n",
+						      __func__);
+					head = prev_head;
+					drbr_putback(ifp, pq->bufring, m);
+					goto escape;
+				}
+				slot = ring->slot + head;
+				nmbuf = NMB(na, slot);
+				nmbuf_bytes = 0;
 			}
-
-			slot->len = nmbuf_bytes;
-			slot->flags = NS_MOREFRAG;
-			head = nm_next(head, lim);
-			slot = ring->slot + head;
-			nmbuf = NMB(na, slot);
-			nmbuf_bytes = 0;
 		}
-	}
 
-	m_freem(m);
+		/* Complete last slot and update head. */
+		slot->len = nmbuf_bytes;
+		slot->flags = 0;
+		head = nm_next(head, lim);
 
-	/* Complete last slot and update head. */
-	slot->len = nmbuf_bytes;
-	slot->flags = 0;
-	ring->head = ring->cur = nm_next(head, lim);
+		/* Consume the packet just processed. */
+		drbr_advance(ifp, pq->bufring);
+		m_freem(m);
+	}
+escape:
+	if (head != ring->head) {
+		/* Some packets have been pushed to the netmap ring. We have
+		 * to tell the host to process the new packets, updating cur
+		 * and head in the CSB. */
+		ring->head = ring->cur = head;
 
-	/* nm_txsync_prologue */
-	kring->rcur = kring->rhead = ring->head;
+		/* nm_txsync_prologue */
+		kring->rcur = kring->rhead = ring->head;
 
-	/* Tell the host to process the new packets, updating cur and
-	 * head in the CSB. */
-	ptnetmap_guest_write_kring_csb(ptring, kring->rcur, kring->rhead);
+		ptnetmap_guest_write_kring_csb(ptring, kring->rcur, kring->rhead);
 
-        /* Kick the host if needed. */
-	if (NM_ACCESS_ONCE(ptring->host_need_kick)) {
-		ptring->sync_flags = NAF_FORCE_RECLAIM;
-		bus_write_4(sc->iomem, pq->kick, 0);
+		/* Kick the host if needed. */
+		if (NM_ACCESS_ONCE(ptring->host_need_kick)) {
+			ptring->sync_flags = NAF_FORCE_RECLAIM;
+			bus_write_4(sc->iomem, pq->kick, 0);
+		}
 	}
 
-	if (0) {
+	if (head == ring->tail) {
+		/* Reactivate the interrupts so that we can be notified
+		 * when some netmap slots are made available by the host. */
 		ptring->guest_need_kick = 1;
 	}
-out:
+
 	PTNET_Q_UNLOCK(pq);
 
 	return 0;



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