socsvn commit: r305574 - soc2016/vincenzo/head/sys/dev/netmap
vincenzo at FreeBSD.org
vincenzo at FreeBSD.org
Mon Jun 27 09:33:19 UTC 2016
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;
More information about the svn-soc-all
mailing list