Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 14 Mar 2020 19:51:55 +0000 (UTC)
From:      Patrick Kelsey <pkelsey@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r358996 - head/sys/net
Message-ID:  <202003141951.02EJptLc099988@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pkelsey
Date: Sat Mar 14 19:51:55 2020
New Revision: 358996
URL: https://svnweb.freebsd.org/changeset/base/358996

Log:
  Fix iflib zero-length fragment handling
  
  The dmamap for zero-length fragments should not be unloaded, as doing
  so breaks the the cluster-reuse logic in _iflib_fl_refill().
  
  All zero-length fragments are now handled by the assemble_segments()
  path so that the cluster-reuse logic there does not have to be
  replicated in the small-single-fragment-packet path of
  iflib_rxd_pkt_get().
  
  Packets consisting entirely of zero-length fragments (which result in
  a NULL mbuf pointer) are now properly tolerated.  This allows drivers
  (such as the vmx driver) to pass such packets to iflib when a
  descriptor error occurs during packet reception, the advantage being
  that the refill of descriptors associated with the error packet are
  handled via the existing iflib machinery without having to duplicate
  parts of that machinery in the driver to handle that error case.
  
  Reviewed by:	avg, erj, gallatin
  MFC after:	1 week
  Differential Revision:	https://reviews.freebsd.org/D23945

Modified:
  head/sys/net/iflib.c

Modified: head/sys/net/iflib.c
==============================================================================
--- head/sys/net/iflib.c	Sat Mar 14 19:43:44 2020	(r358995)
+++ head/sys/net/iflib.c	Sat Mar 14 19:51:55 2020	(r358996)
@@ -2550,7 +2550,8 @@ rxd_frag_to_sd(iflib_rxq_t rxq, if_rxd_frag_t irf, boo
 	MPASS(fl->ifl_cidx == cidx);
 	bus_dmamap_sync(fl->ifl_buf_tag, map, BUS_DMASYNC_POSTREAD);
 
-	if (rxq->pfil != NULL && PFIL_HOOKED_IN(rxq->pfil) && pf_rv != NULL) {
+	if (rxq->pfil != NULL && PFIL_HOOKED_IN(rxq->pfil) && pf_rv != NULL &&
+	    irf->irf_len != 0) {
 		payload  = *sd->ifsd_cl;
 		payload +=  ri->iri_pad;
 		len = ri->iri_len - ri->iri_pad;
@@ -2587,7 +2588,7 @@ rxd_frag_to_sd(iflib_rxq_t rxq, if_rxd_frag_t irf, boo
 		*pf_rv = PFIL_PASS;
 	}
 
-	if (unload)
+	if (unload && irf->irf_len != 0)
 		bus_dmamap_unload(fl->ifl_buf_tag, map);
 	fl->ifl_cidx = (fl->ifl_cidx + 1) & (fl->ifl_size-1);
 	if (__predict_false(fl->ifl_cidx == 0))
@@ -2672,6 +2673,7 @@ iflib_rxd_pkt_get(iflib_rxq_t rxq, if_rxd_info_t ri)
 
 	/* should I merge this back in now that the two paths are basically duplicated? */
 	if (ri->iri_nfrags == 1 &&
+	    ri->iri_frags[0].irf_len != 0 &&
 	    ri->iri_frags[0].irf_len <= MIN(IFLIB_RX_COPY_THRESH, MHLEN)) {
 		m = rxd_frag_to_sd(rxq, &ri->iri_frags[0], false, &sd,
 		    &pf_rv, ri);
@@ -2688,6 +2690,8 @@ iflib_rxd_pkt_get(iflib_rxq_t rxq, if_rxd_info_t ri)
 		}
 	} else {
 		m = assemble_segments(rxq, ri, &sd, &pf_rv);
+		if (m == NULL)
+			return (NULL);
 		if (pf_rv != PFIL_PASS && pf_rv != PFIL_REALLOCED)
 			return (m);
 	}



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