Date: Tue, 29 Sep 2020 23:35:46 +0000 (UTC) From: Navdeep Parhar <np@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r366272 - in stable/12/sys/dev/cxgbe: . tom Message-ID: <202009292335.08TNZkD0096205@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202009292335.08TNZkD0096205>