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>