svn commit: r275554 - head/sys/dev/cxgbe

Navdeep Parhar np at FreeBSD.org
Sat Dec 6 01:47:39 UTC 2014


Author: np
Date: Sat Dec  6 01:47:38 2014
New Revision: 275554
URL: https://svnweb.freebsd.org/changeset/base/275554

Log:
  cxgbe(4): allow the driver to use rx buffers that do not end on a pack
  boundary.
  
  MFC after:	2 weeks

Modified:
  head/sys/dev/cxgbe/adapter.h
  head/sys/dev/cxgbe/t4_sge.c

Modified: head/sys/dev/cxgbe/adapter.h
==============================================================================
--- head/sys/dev/cxgbe/adapter.h	Sat Dec  6 01:21:12 2014	(r275553)
+++ head/sys/dev/cxgbe/adapter.h	Sat Dec  6 01:47:38 2014	(r275554)
@@ -148,7 +148,7 @@ enum {
 #else
 	SW_ZONE_SIZES = 3,	/* cluster, jumbo9k, jumbo16k */
 #endif
-	CL_METADATA_SIZE = 256,	/* same as MSIZE for now */
+	CL_METADATA_SIZE = CACHE_LINE_SIZE,
 
 	SGE_MAX_WR_NDESC = SGE_MAX_WR_LEN / EQ_ESIZE, /* max WR size in desc */
 	TX_SGL_SEGS = 36,

Modified: head/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- head/sys/dev/cxgbe/t4_sge.c	Sat Dec  6 01:21:12 2014	(r275553)
+++ head/sys/dev/cxgbe/t4_sge.c	Sat Dec  6 01:47:38 2014	(r275554)
@@ -489,24 +489,17 @@ t4_tweak_chip_settings(struct adapter *s
 
 /*
  * SGE wants the buffer to be at least 64B and then a multiple of 16.  If
- * padding and packing are enabled, the buffer's start and end need to be
- * correctly aligned as well.  We'll just make sure that the size is a multiple
- * of the alignment, it is up to other parts .
+ * padding is is use the buffer's start and end need to be aligned to the pad
+ * boundary as well.  We'll just make sure that the size is a multiple of the
+ * boundary here, it is up to the buffer allocation code to make sure the start
+ * of the buffer is aligned as well.
  */
 static inline int
 hwsz_ok(struct adapter *sc, int hwsz)
 {
-	int align = 16;
-
-	if (fl_pad) {
-		MPASS(sc->sge.pad_boundary > align);
-		align = sc->sge.pad_boundary;
-	}
-	if (buffer_packing && sc->sge.pack_boundary > align)
-		align = sc->sge.pack_boundary;
-	align--;	/* now a mask */
-	return (hwsz >= 64 && (hwsz & align) == 0);
+	int mask = fl_pad ? sc->sge.pad_boundary - 1 : 16 - 1;
 
+	return (hwsz >= 64 && (hwsz & mask) == 0);
 }
 
 /*
@@ -600,9 +593,6 @@ t4_read_chip_settings(struct adapter *sc
 			MPASS(powerof2(swz->size));
 			if (fl_pad && (swz->size % sc->sge.pad_boundary != 0))
 				continue;
-			if (buffer_packing &&
-			    (swz->size % sc->sge.pack_boundary != 0))
-				continue;
 		}
 
 		if (swz->size == safest_rx_cluster)
@@ -615,8 +605,6 @@ t4_read_chip_settings(struct adapter *sc
 #ifdef INVARIANTS
 			if (fl_pad)
 				MPASS(hwb->size % sc->sge.pad_boundary == 0);
-			if (buffer_packing)
-				MPASS(hwb->size % sc->sge.pack_boundary == 0);
 #endif
 			hwb->zidx = i;
 			if (head == -1)
@@ -668,8 +656,6 @@ t4_read_chip_settings(struct adapter *sc
 #ifdef INVARIANTS
 			if (fl_pad)
 				MPASS(hwb->size % sc->sge.pad_boundary == 0);
-			if (buffer_packing)
-				MPASS(hwb->size % sc->sge.pack_boundary == 0);
 #endif
 			spare = safe_swz->size - hwb->size;
 			if (spare >= CL_METADATA_SIZE) {
@@ -1571,7 +1557,8 @@ rxb_free(struct mbuf *m, void *arg1, voi
  * d) m_extaddref (cluster with metadata) zone_mbuf
  */
 static struct mbuf *
-get_scatter_segment(struct adapter *sc, struct sge_fl *fl, int total, int flags)
+get_scatter_segment(struct adapter *sc, struct sge_fl *fl, int fr_offset,
+    int remaining)
 {
 	struct mbuf *m;
 	struct fl_sdesc *sd = &fl->sdesc[fl->cidx];
@@ -1579,26 +1566,31 @@ get_scatter_segment(struct adapter *sc, 
 	struct sw_zone_info *swz = &sc->sge.sw_zone_info[cll->zidx];
 	struct hw_buf_info *hwb = &sc->sge.hw_buf_info[cll->hwidx];
 	struct cluster_metadata *clm = cl_metadata(sc, fl, cll, sd->cl);
-	int len, padded_len;
+	int len, blen;
 	caddr_t payload;
 
-	len = min(total, hwb->size - fl->rx_offset);
+	blen = hwb->size - fl->rx_offset;	/* max possible in this buf */
+	len = min(remaining, blen);
 	payload = sd->cl + cll->region1 + fl->rx_offset;
 	if (fl->flags & FL_BUF_PACKING) {
-		padded_len = roundup2(len, fl->buf_boundary);
-		MPASS(fl->rx_offset + padded_len <= hwb->size);
+		const u_int l = fr_offset + len;
+		const u_int pad = roundup2(l, fl->buf_boundary) - l;
+
+		if (fl->rx_offset + len + pad < hwb->size)
+			blen = len + pad;
+		MPASS(fl->rx_offset + blen <= hwb->size);
 	} else {
-		padded_len = hwb->size;
 		MPASS(fl->rx_offset == 0);	/* not packing */
 	}
 
+
 	if (sc->sc_do_rxcopy && len < RX_COPY_THRESHOLD) {
 
 		/*
 		 * Copy payload into a freshly allocated mbuf.
 		 */
 
-		m = flags & M_PKTHDR ?
+		m = fr_offset == 0 ?
 		    m_gethdr(M_NOWAIT, MT_DATA) : m_get(M_NOWAIT, MT_DATA);
 		if (m == NULL)
 			return (NULL);
@@ -1620,10 +1612,11 @@ get_scatter_segment(struct adapter *sc, 
 		MPASS(clm != NULL);
 		m = (struct mbuf *)(sd->cl + sd->nmbuf * MSIZE);
 		/* No bzero required */
-		if (m_init(m, NULL, 0, M_NOWAIT, MT_DATA, flags | M_NOFREE))
+		if (m_init(m, NULL, 0, M_NOWAIT, MT_DATA,
+		    fr_offset == 0 ? M_PKTHDR | M_NOFREE : M_NOFREE))
 			return (NULL);
 		fl->mbuf_inlined++;
-		m_extaddref(m, payload, padded_len, &clm->refcount, rxb_free,
+		m_extaddref(m, payload, blen, &clm->refcount, rxb_free,
 		    swz->zone, sd->cl);
 		if (sd->nmbuf++ == 0)
 			counter_u64_add(extfree_refs, 1);
@@ -1635,13 +1628,13 @@ get_scatter_segment(struct adapter *sc, 
 		 * payload in the cluster.
 		 */
 
-		m = flags & M_PKTHDR ?
+		m = fr_offset == 0 ?
 		    m_gethdr(M_NOWAIT, MT_DATA) : m_get(M_NOWAIT, MT_DATA);
 		if (m == NULL)
 			return (NULL);
 		fl->mbuf_allocated++;
 		if (clm != NULL) {
-			m_extaddref(m, payload, padded_len, &clm->refcount,
+			m_extaddref(m, payload, blen, &clm->refcount,
 			    rxb_free, swz->zone, sd->cl);
 			if (sd->nmbuf++ == 0)
 				counter_u64_add(extfree_refs, 1);
@@ -1650,12 +1643,12 @@ get_scatter_segment(struct adapter *sc, 
 			sd->cl = NULL;	/* consumed, not a recycle candidate */
 		}
 	}
-	if (flags & M_PKTHDR)
-		m->m_pkthdr.len = total;
+	if (fr_offset == 0)
+		m->m_pkthdr.len = remaining;
 	m->m_len = len;
 
 	if (fl->flags & FL_BUF_PACKING) {
-		fl->rx_offset += padded_len;
+		fl->rx_offset += blen;
 		MPASS(fl->rx_offset <= hwb->size);
 		if (fl->rx_offset < hwb->size)
 			return (m);	/* without advancing the cidx */
@@ -1677,17 +1670,17 @@ static struct mbuf *
 get_fl_payload(struct adapter *sc, struct sge_fl *fl, uint32_t len_newbuf)
 {
 	struct mbuf *m0, *m, **pnext;
-	u_int len;
+	u_int remaining;
+	const u_int total = G_RSPD_LEN(len_newbuf);
 
-	len = G_RSPD_LEN(len_newbuf);
 	if (__predict_false(fl->flags & FL_BUF_RESUME)) {
 		M_ASSERTPKTHDR(fl->m0);
-		MPASS(len == fl->m0->m_pkthdr.len);
-		MPASS(fl->remaining < len);
+		MPASS(fl->m0->m_pkthdr.len == total);
+		MPASS(fl->remaining < total);
 
 		m0 = fl->m0;
 		pnext = fl->pnext;
-		len = fl->remaining;
+		remaining = fl->remaining;
 		fl->flags &= ~FL_BUF_RESUME;
 		goto get_segment;
 	}
@@ -1708,25 +1701,25 @@ get_fl_payload(struct adapter *sc, struc
 	 * 'len' and it may span multiple hw buffers.
 	 */
 
-	m0 = get_scatter_segment(sc, fl, len, M_PKTHDR);
+	m0 = get_scatter_segment(sc, fl, 0, total);
 	if (m0 == NULL)
 		return (NULL);
-	len -= m0->m_len;
+	remaining = total - m0->m_len;
 	pnext = &m0->m_next;
-	while (len > 0) {
+	while (remaining > 0) {
 get_segment:
 		MPASS(fl->rx_offset == 0);
-		m = get_scatter_segment(sc, fl, len, 0);
+		m = get_scatter_segment(sc, fl, total - remaining, remaining);
 		if (__predict_false(m == NULL)) {
 			fl->m0 = m0;
 			fl->pnext = pnext;
-			fl->remaining = len;
+			fl->remaining = remaining;
 			fl->flags |= FL_BUF_RESUME;
 			return (NULL);
 		}
 		*pnext = m;
 		pnext = &m->m_next;
-		len -= m->m_len;
+		remaining -= m->m_len;
 	}
 	*pnext = NULL;
 
@@ -4485,8 +4478,7 @@ find_safe_refill_source(struct adapter *
 	fl->cll_alt.hwidx = hwidx;
 	fl->cll_alt.zidx = hwb->zidx;
 	if (allow_mbufs_in_cluster &&
-	    (fl_pad == 0 || (MSIZE % sc->sge.pad_boundary) == 0) &&
-	    (!(fl->flags & FL_BUF_PACKING) || (MSIZE % sc->sge.pack_boundary) == 0))
+	    (fl_pad == 0 || (MSIZE % sc->sge.pad_boundary) == 0))
 		fl->cll_alt.region1 = ((spare - CL_METADATA_SIZE) / MSIZE) * MSIZE;
 	else
 		fl->cll_alt.region1 = 0;


More information about the svn-src-all mailing list