Date: Fri, 8 Jul 2016 15:43:19 GMT From: vincenzo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r305822 - soc2016/vincenzo/head/sys/dev/netmap Message-ID: <201607081543.u68FhJlj006863@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: vincenzo Date: Fri Jul 8 15:43:19 2016 New Revision: 305822 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=305822 Log: freebsd: ptnet_rx_eof: handle errors 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 Fri Jul 8 15:43:10 2016 (r305821) +++ soc2016/vincenzo/head/sys/dev/netmap/if_ptnet.c Fri Jul 8 15:43:19 2016 (r305822) @@ -1550,9 +1550,10 @@ kring->nr_kflags &= ~NKR_PENDINTR; for (;;) { + unsigned int prev_head = head; + struct mbuf *mhead, *mtail; struct netmap_slot *slot; unsigned int nmbuf_len; - struct mbuf *mhead, *mtail; uint8_t *nmbuf, *mdata; if (budget == 0) { @@ -1582,7 +1583,8 @@ } } - /* We use m_getcl() to allocate an mbuf with standard cluster + /* Allocate the head of an mbuf chain. + * We use m_getcl() to allocate an mbuf with standard cluster * size (MCLBYTES). In the future we could use m_getjcl() * to choose different sizes. */ mhead = mtail = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); @@ -1606,7 +1608,7 @@ mdata = mtod(mtail, uint8_t *); mtail->m_len = 0; - do { + for (;;) { slot = ring->slot + head; nmbuf_len = slot->len; nmbuf = NMB(na, slot); @@ -1625,10 +1627,22 @@ struct mbuf *mf; mf = m_getcl(M_NOWAIT, MT_DATA, 0); - if (!mf) { - /* XXX handle error */ - break; + if (unlikely(!mf)) { + /* Ouch. We ran out of memory + * while processing a packet. + * We have to restore the + * previous head position, + * free the mbuf chain, and + * schedule the taskqueue to + * give the packet another + * chance. */ + head = prev_head; + m_freem(mhead); + taskqueue_enqueue(pq->taskq, + &pq->task); + goto escape; } + mtail->m_next = mf; mtail = mf; mdata = mtod(mtail, uint8_t *); @@ -1649,7 +1663,20 @@ } while (nmbuf_len); head = nm_next(head, lim); - } while (slot->flags & NS_MOREFRAG); + + if (!(slot->flags & NS_MOREFRAG)) { + break; + } + + if (unlikely(head == ring->tail)) { + /* The very last slot prepared by the host has + * the NS_MOREFRAG set. This is an error that + * we handle by accepting the truncated packet, + * and let the network stack drop it. */ + RD(1, "Warning: Truncating incomplete packet"); + break; + } + } PTNET_Q_UNLOCK(pq); (*ifp->if_input)(ifp, mhead); @@ -1657,7 +1684,7 @@ budget--; } - +escape: if (head != ring->head) { /* Some packets have been pushed to the network stack. * We need to update the CSB to tell the host about the new
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607081543.u68FhJlj006863>