svn commit: r366272 - in stable/12/sys/dev/cxgbe: . tom

Navdeep Parhar np at FreeBSD.org
Tue Sep 29 23:35:47 UTC 2020


Author: np
Date: Tue Sep 29 23:35:46 2020
New Revision: 366272
URL: https://svnweb.freebsd.org/changeset/base/366272

Log:
  MFC r349533 (by jhb@).
  
  Note that this does not add any functionality as IFCAP_NOMAP doesn't
  exist on 12.  This is mainly an attempt to get t4_sge.c closer to what's
  in head (to help with other MFCs).
  
  r349533:
  Add support for IFCAP_NOMAP to cxgbe(4).
  
  Since cxgbe(4) uses sglist instead of bus_dma, this required updates
  to the code that generates scatter/gather lists for packets.  Also,
  unmapped mbufs are always sent via DMA and never as immediate data in
  the payload of a work request.

Modified:
  stable/12/sys/dev/cxgbe/adapter.h
  stable/12/sys/dev/cxgbe/t4_main.c
  stable/12/sys/dev/cxgbe/t4_sge.c
  stable/12/sys/dev/cxgbe/tom/t4_cpl_io.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/dev/cxgbe/adapter.h
==============================================================================
--- stable/12/sys/dev/cxgbe/adapter.h	Tue Sep 29 23:21:56 2020	(r366271)
+++ stable/12/sys/dev/cxgbe/adapter.h	Tue Sep 29 23:35:46 2020	(r366272)
@@ -82,6 +82,10 @@ prefetch(void *x)
 #define CTLTYPE_U64 CTLTYPE_QUAD
 #endif
 
+#ifndef IFCAP_NOMAP
+#define IFCAP_NOMAP (0)
+#endif
+
 SYSCTL_DECL(_hw_cxgbe);
 
 struct adapter;

Modified: stable/12/sys/dev/cxgbe/t4_main.c
==============================================================================
--- stable/12/sys/dev/cxgbe/t4_main.c	Tue Sep 29 23:21:56 2020	(r366271)
+++ stable/12/sys/dev/cxgbe/t4_main.c	Tue Sep 29 23:35:46 2020	(r366272)
@@ -1653,7 +1653,7 @@ cxgbe_probe(device_t dev)
 #define T4_CAP (IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU | IFCAP_HWCSUM | \
     IFCAP_VLAN_HWCSUM | IFCAP_TSO | IFCAP_JUMBO_MTU | IFCAP_LRO | \
     IFCAP_VLAN_HWTSO | IFCAP_LINKSTATE | IFCAP_HWCSUM_IPV6 | IFCAP_HWSTATS | \
-    IFCAP_HWRXTSTMP)
+    IFCAP_HWRXTSTMP | IFCAP_NOMAP)
 #define T4_CAP_ENABLE (T4_CAP)
 
 static int
@@ -2018,6 +2018,8 @@ cxgbe_ioctl(struct ifnet *ifp, unsigned long cmd, cadd
 					rxq->iq.flags &= ~IQ_RX_TIMESTAMP;
 			}
 		}
+		if (mask & IFCAP_NOMAP)
+			ifp->if_capenable ^= IFCAP_NOMAP;
 
 #ifdef VLAN_CAPABILITIES
 		VLAN_CAPABILITIES(ifp);

Modified: stable/12/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- stable/12/sys/dev/cxgbe/t4_sge.c	Tue Sep 29 23:21:56 2020	(r366271)
+++ stable/12/sys/dev/cxgbe/t4_sge.c	Tue Sep 29 23:35:46 2020	(r366272)
@@ -83,6 +83,7 @@ __FBSDID("$FreeBSD$");
 #endif
 
 /* Internal mbuf flags stored in PH_loc.eight[1]. */
+#define	MC_NOMAP		0x01
 #define	MC_RAW_WR		0x02
 
 /*
@@ -2311,15 +2312,80 @@ m_advance(struct mbuf **pm, int *poffset, int len)
 	return ((void *)p);
 }
 
+#if IFCAP_NOMAP != 0
+static inline int
+count_mbuf_ext_pgs(struct mbuf *m, int skip, vm_paddr_t *nextaddr)
+{
+	struct mbuf_ext_pgs *ext_pgs;
+	vm_paddr_t paddr;
+	int i, len, off, pglen, pgoff, seglen, segoff;
+	int nsegs = 0;
+
+	MBUF_EXT_PGS_ASSERT(m);
+	ext_pgs = m->m_ext.ext_pgs;
+	off = mtod(m, vm_offset_t);
+	len = m->m_len;
+	off += skip;
+	len -= skip;
+
+	if (ext_pgs->hdr_len != 0) {
+		if (off >= ext_pgs->hdr_len) {
+			off -= ext_pgs->hdr_len;
+		} else {
+			seglen = ext_pgs->hdr_len - off;
+			segoff = off;
+			seglen = min(seglen, len);
+			off = 0;
+			len -= seglen;
+			paddr = pmap_kextract(
+			    (vm_offset_t)&ext_pgs->hdr[segoff]);
+			if (*nextaddr != paddr)
+				nsegs++;
+			*nextaddr = paddr + seglen;
+		}
+	}
+	pgoff = ext_pgs->first_pg_off;
+	for (i = 0; i < ext_pgs->npgs && len > 0; i++) {
+		pglen = mbuf_ext_pg_len(ext_pgs, i, pgoff);
+		if (off >= pglen) {
+			off -= pglen;
+			pgoff = 0;
+			continue;
+		}
+		seglen = pglen - off;
+		segoff = pgoff + off;
+		off = 0;
+		seglen = min(seglen, len);
+		len -= seglen;
+		paddr = ext_pgs->pa[i] + segoff;
+		if (*nextaddr != paddr)
+			nsegs++;
+		*nextaddr = paddr + seglen;
+		pgoff = 0;
+	};
+	if (len != 0) {
+		seglen = min(len, ext_pgs->trail_len - off);
+		len -= seglen;
+		paddr = pmap_kextract((vm_offset_t)&ext_pgs->trail[off]);
+		if (*nextaddr != paddr)
+			nsegs++;
+		*nextaddr = paddr + seglen;
+	}
+
+	return (nsegs);
+}
+#endif
+
+
 /*
  * Can deal with empty mbufs in the chain that have m_len = 0, but the chain
  * must have at least one mbuf that's not empty.  It is possible for this
  * routine to return 0 if skip accounts for all the contents of the mbuf chain.
  */
 static inline int
-count_mbuf_nsegs(struct mbuf *m, int skip)
+count_mbuf_nsegs(struct mbuf *m, int skip, uint8_t *cflags)
 {
-	vm_paddr_t lastb, next;
+	vm_paddr_t nextaddr, paddr;
 	vm_offset_t va;
 	int len, nsegs;
 
@@ -2328,9 +2394,8 @@ count_mbuf_nsegs(struct mbuf *m, int skip)
 	MPASS(m->m_pkthdr.len >= skip);
 
 	nsegs = 0;
-	lastb = 0;
+	nextaddr = 0;
 	for (; m; m = m->m_next) {
-
 		len = m->m_len;
 		if (__predict_false(len == 0))
 			continue;
@@ -2338,14 +2403,22 @@ count_mbuf_nsegs(struct mbuf *m, int skip)
 			skip -= len;
 			continue;
 		}
+#if IFCAP_NOMAP != 0
+		if ((m->m_flags & M_NOMAP) != 0) {
+			*cflags |= MC_NOMAP;
+			nsegs += count_mbuf_ext_pgs(m, skip, &nextaddr);
+			skip = 0;
+			continue;
+		}
+#endif
 		va = mtod(m, vm_offset_t) + skip;
 		len -= skip;
 		skip = 0;
-		next = pmap_kextract(va);
+		paddr = pmap_kextract(va);
 		nsegs += sglist_count((void *)(uintptr_t)va, len);
-		if (lastb + 1 == next)
+		if (paddr == nextaddr)
 			nsegs--;
-		lastb = pmap_kextract(va + len - 1);
+		nextaddr = pmap_kextract(va + len - 1) + 1;
 	}
 
 	return (nsegs);
@@ -2367,7 +2440,9 @@ parse_pkt(struct adapter *sc, struct mbuf **mp)
 	struct tcphdr *tcp;
 #endif
 	uint16_t eh_type;
+	uint8_t cflags;
 
+	cflags = 0;
 	M_ASSERTPKTHDR(m0);
 	if (__predict_false(m0->m_pkthdr.len < ETHER_HDR_LEN)) {
 		rc = EINVAL;
@@ -2383,7 +2458,7 @@ restart:
 	 */
 	M_ASSERTPKTHDR(m0);
 	MPASS(m0->m_pkthdr.len > 0);
-	nsegs = count_mbuf_nsegs(m0, 0);
+	nsegs = count_mbuf_nsegs(m0, 0, &cflags);
 	if (nsegs > (needs_tso(m0) ? TX_SGL_SEGS_TSO : TX_SGL_SEGS)) {
 		if (defragged++ > 0 || (m = m_defrag(m0, M_NOWAIT)) == NULL) {
 			rc = EFBIG;
@@ -2393,7 +2468,8 @@ restart:
 		goto restart;
 	}
 
-	if (__predict_false(nsegs > 2 && m0->m_pkthdr.len <= MHLEN)) {
+	if (__predict_false(nsegs > 2 && m0->m_pkthdr.len <= MHLEN &&
+	    !(cflags & MC_NOMAP))) {
 		m0 = m_pullup(m0, m0->m_pkthdr.len);
 		if (m0 == NULL) {
 			/* Should have left well enough alone. */
@@ -2404,7 +2480,7 @@ restart:
 		goto restart;
 	}
 	set_mbuf_nsegs(m0, nsegs);
-	set_mbuf_cflags(m0, 0);
+	set_mbuf_cflags(m0, cflags);
 	if (sc->flags & IS_VF)
 		set_mbuf_len16(m0, txpkt_vm_len16(nsegs, needs_tso(m0)));
 	else
@@ -2490,7 +2566,9 @@ restart:
 		/* EO WRs have the headers in the WR and not the GL. */
 		immhdrs = m0->m_pkthdr.l2hlen + m0->m_pkthdr.l3hlen +
 		    m0->m_pkthdr.l4hlen;
-		nsegs = count_mbuf_nsegs(m0, immhdrs);
+		cflags = 0;
+		nsegs = count_mbuf_nsegs(m0, immhdrs, &cflags);
+		MPASS(cflags == mbuf_cflags(m0));
 		set_mbuf_eo_nsegs(m0, nsegs);
 		set_mbuf_eo_len16(m0,
 		    txpkt_eo_len16(nsegs, immhdrs, needs_tso(m0)));
@@ -4652,7 +4730,8 @@ write_txpkt_wr(struct adapter *sc, struct sge_txq *txq
 	ctrl = sizeof(struct cpl_tx_pkt_core);
 	if (needs_tso(m0))
 		ctrl += sizeof(struct cpl_tx_pkt_lso_core);
-	else if (pktlen <= imm_payload(2) && available >= 2) {
+	else if (!(mbuf_cflags(m0) & MC_NOMAP) && pktlen <= imm_payload(2) &&
+	    available >= 2) {
 		/* Immediate data.  Recalculate len16 and set nsegs to 0. */
 		ctrl += pktlen;
 		len16 = howmany(sizeof(struct fw_eth_tx_pkt_wr) +

Modified: stable/12/sys/dev/cxgbe/tom/t4_cpl_io.c
==============================================================================
--- stable/12/sys/dev/cxgbe/tom/t4_cpl_io.c	Tue Sep 29 23:21:56 2020	(r366271)
+++ stable/12/sys/dev/cxgbe/tom/t4_cpl_io.c	Tue Sep 29 23:35:46 2020	(r366272)
@@ -634,6 +634,10 @@ write_tx_sgl(void *dst, struct mbuf *start, struct mbu
 		if (IS_AIOTX_MBUF(m))
 			rc = sglist_append_vmpages(&sg, aiotx_mbuf_pages(m),
 			    aiotx_mbuf_pgoff(m), m->m_len);
+#if IFCAP_NOMAP != 0
+		else if (m->m_flags & M_NOMAP)
+			rc = sglist_append_mb_ext_pgs(&sg, m);
+#endif
 		else
 			rc = sglist_append(&sg, mtod(m, void *), m->m_len);
 		if (__predict_false(rc != 0))
@@ -755,6 +759,10 @@ t4_push_frames(struct adapter *sc, struct toepcb *toep
 			if (IS_AIOTX_MBUF(m))
 				n = sglist_count_vmpages(aiotx_mbuf_pages(m),
 				    aiotx_mbuf_pgoff(m), m->m_len);
+#if IFCAP_NOMAP != 0
+			else if (m->m_flags & M_NOMAP)
+				n = sglist_count_mb_ext_pgs(m);
+#endif
 			else
 				n = sglist_count(mtod(m, void *), m->m_len);
 


More information about the svn-src-all mailing list