PERFORCE change 118142 for review

Matt Jacob mjacob at FreeBSD.org
Sun Apr 15 06:35:43 UTC 2007


http://perforce.freebsd.org/chv.cgi?CH=118142

Change 118142 by mjacob at mjexp on 2007/04/15 06:34:53

	More IFC.

Affected files ...

.. //depot/projects/mjexp/sys/dev/cxgb/cxgb_main.c#3 integrate
.. //depot/projects/mjexp/sys/dev/cxgb/cxgb_sge.c#5 integrate
.. //depot/projects/mjexp/sys/dev/cxgb/sys/uipc_mvec.c#3 integrate
.. //depot/projects/mjexp/sys/sys/mbuf.h#8 integrate

Differences ...

==== //depot/projects/mjexp/sys/dev/cxgb/cxgb_main.c#3 (text+ko) ====

@@ -32,7 +32,7 @@
 ***************************************************************************/
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_main.c,v 1.13 2007/04/14 20:40:22 kmacy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_main.c,v 1.14 2007/04/15 05:45:09 kmacy Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -167,6 +167,7 @@
 
 #define SGE_MSIX_COUNT (SGE_QSETS + 1)
 
+extern int collapse_mbufs;
 /*
  * The driver uses the best interrupt scheme available on a platform in the
  * order MSI-X, MSI, legacy pin interrupts.  This parameter determines which
@@ -1339,8 +1340,8 @@
 		}
 		m_sanity(m0, 0);
 		m0 = m;
-#endif		
-		if (m->m_pkthdr.len > MCLBYTES &&
+#endif
+		if (collapse_mbufs && m->m_pkthdr.len > MCLBYTES &&
 		    m_collapse(m, TX_MAX_SEGS, &m0) == EFBIG) {
 			if ((m0 = m_defrag(m, M_NOWAIT)) != NULL) {
 				m = m0;

==== //depot/projects/mjexp/sys/dev/cxgb/cxgb_sge.c#5 (text+ko) ====

@@ -32,7 +32,7 @@
 ***************************************************************************/
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_sge.c,v 1.11 2007/04/14 20:40:22 kmacy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/cxgb/cxgb_sge.c,v 1.12 2007/04/15 05:45:10 kmacy Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -71,7 +71,7 @@
 
 uint32_t collapse_free = 0;
 uint32_t mb_free_vec_free = 0;
-
+int      collapse_mbufs = 1;
 
 #define USE_GTS 0
 
@@ -837,13 +837,6 @@
 	m0 = *m;
 	pktlen = m0->m_pkthdr.len;
 
-	if ((stx->flags & TX_SW_DESC_MAP_CREATED) == 0) {
-		if ((err = bus_dmamap_create(txq->entry_tag, 0, &stx->map))) {
-			log(LOG_WARNING, "bus_dmamap_create failed %d\n", err);
-			return (err);
-		}
-		stx->flags |= TX_SW_DESC_MAP_CREATED;
-	}
 	err = bus_dmamap_load_mvec_sg(txq->entry_tag, stx->map, m0, segs, nsegs, 0);
 #ifdef DEBUG		
 	if (err) {
@@ -2264,7 +2257,10 @@
 	    "mb_free_vec_free",
 	    CTLFLAG_RD, &mb_free_vec_free,
 	    0, "frees during mb_free_vec");
-
+	SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
+	    "collapse_mbufs",
+	    CTLFLAG_RW, &collapse_mbufs,
+	    0, "collapse mbuf chains into iovecs");
 }
 
 /**

==== //depot/projects/mjexp/sys/dev/cxgb/sys/uipc_mvec.c#3 (text+ko) ====

@@ -29,7 +29,7 @@
  ***************************************************************************/
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/cxgb/sys/uipc_mvec.c,v 1.5 2007/04/14 20:38:38 kmacy Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/cxgb/sys/uipc_mvec.c,v 1.7 2007/04/15 05:46:34 kmacy Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -42,11 +42,7 @@
 
 #include <machine/bus.h>
 #include <dev/cxgb/sys/mvec.h>
-
 #include "opt_zero.h"
-#ifdef ZERO_COPY_SOCKETS
-#error "ZERO_COPY_SOCKETS not supported with mvec"
-#endif
 
 #ifdef DEBUG
 #define DPRINTF printf
@@ -137,19 +133,7 @@
 	m->m_next = head;
 	head = m;
 	M_SANITY(m, 0);
-#ifdef INVARIANTS
-	len = head->m_len;
-	m = m->m_next;
-	while (m) {
-		KASSERT((m->m_flags & M_PKTHDR) == 0,
-		    ("pkthdr set on intermediate mbuf - post"));
-		len += m->m_len;
-		m = m->m_next;
-		
-	}
-	if (len != head->m_pkthdr.len)
-		panic("len=%d pktlen=%d", len, head->m_pkthdr.len);
-#endif
+
 	return (0);
 } 
 
@@ -161,12 +145,14 @@
 	for (i = 0; i < max; i++) {
 		if (m == NULL)
 			break;
-#ifndef PACKET_ZONE_DISABLED
+#ifndef MBUF_PACKET_ZONE_DISABLE
 		if ((m->m_flags & M_EXT) && (m->m_ext.ext_type == EXT_PACKET))
 			return (EINVAL);
 #endif
-		if (m->m_len == 0)
-			DPRINTF("m=%p is len=0\n", m);
+#ifdef ZERO_COPY_SOCKETS
+		if ((m->m_flags & M_EXT) && (m->m_ext.ext_type == EXT_SFBUF))		
+			return (EINVAL);
+#endif
 		M_SANITY(m, 0);
 		vec[i] = m;
 		m = m->m_next;
@@ -398,13 +384,28 @@
 }
 
 #if (!defined(__sparc64__) && !defined(__sun4v__))
-struct mvec_sg_cb_arg {
-	bus_dma_segment_t *segs;
-	int error;
-	int index;
-	int nseg;
+#include <sys/sysctl.h>
+
+#define BUS_DMA_COULD_BOUNCE	BUS_DMA_BUS3
+#define BUS_DMA_MIN_ALLOC_COMP	BUS_DMA_BUS4
+
+struct bounce_zone {
+	STAILQ_ENTRY(bounce_zone) links;
+	STAILQ_HEAD(bp_list, bounce_page) bounce_page_list;
+	int		total_bpages;
+	int		free_bpages;
+	int		reserved_bpages;
+	int		active_bpages;
+	int		total_bounced;
+	int		total_deferred;
+	bus_size_t	alignment;
+	bus_size_t	boundary;
+	bus_addr_t	lowaddr;
+	char		zoneid[8];
+	char		lowaddrid[20];
+	struct sysctl_ctx_list sysctl_tree;
+	struct sysctl_oid *sysctl_tree_top;
 };
-
 struct bus_dma_tag {
 	bus_dma_tag_t	  parent;
 	bus_size_t	  alignment;
@@ -425,23 +426,137 @@
 	struct bounce_zone *bounce_zone;
 };
 
-static void
-mvec_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+struct bus_dmamap {
+	struct bp_list	       bpages;
+	int		       pagesneeded;
+	int		       pagesreserved;
+	bus_dma_tag_t	       dmat;
+	void		      *buf;		/* unmapped buffer pointer */
+	bus_size_t	       buflen;		/* unmapped buffer length */
+	bus_dmamap_callback_t *callback;
+	void		      *callback_arg;
+	STAILQ_ENTRY(bus_dmamap) links;
+};
+
+static struct bus_dmamap nobounce_dmamap;
+
+static __inline int
+run_filter(bus_dma_tag_t dmat, bus_addr_t paddr)
+{
+	int retval;
+
+	retval = 0;
+
+	do {
+		if (((paddr > dmat->lowaddr && paddr <= dmat->highaddr)
+		 || ((paddr & (dmat->alignment - 1)) != 0))
+		 && (dmat->filter == NULL
+		  || (*dmat->filter)(dmat->filterarg, paddr) != 0))
+			retval = 1;
+
+		dmat = dmat->parent;		
+	} while (retval == 0 && dmat != NULL);
+	return (retval);
+}
+
+static __inline int
+_bus_dmamap_load_buffer(bus_dma_tag_t dmat,
+    			bus_dmamap_t map,
+			void *buf, bus_size_t buflen,
+			pmap_t pmap,
+			int flags,
+			bus_addr_t *lastaddrp,
+			bus_dma_segment_t *segs,
+			int *segp,
+			int first)
 {
-	struct mvec_sg_cb_arg *cb_arg = arg;
-	
-	cb_arg->error = error;
-	cb_arg->segs[cb_arg->index] = segs[0];
-	cb_arg->nseg = nseg;
-	KASSERT(nseg == 1, ("nseg=%d", nseg));
+	bus_size_t sgsize;
+	bus_addr_t curaddr, lastaddr, baddr, bmask;
+	vm_offset_t vaddr;
+	int needbounce = 0;
+	int seg;
+
+	if (map == NULL)
+		map = &nobounce_dmamap;
+
+	/* Reserve Necessary Bounce Pages */
+	if (map->pagesneeded != 0)
+		panic("don't support bounce pages");
+
+	vaddr = (vm_offset_t)buf;
+	lastaddr = *lastaddrp;
+	bmask = ~(dmat->boundary - 1);
+
+	for (seg = *segp; buflen > 0 ; ) {
+		/*
+		 * Get the physical address for this segment.
+		 */
+		if (pmap)
+			curaddr = pmap_extract(pmap, vaddr);
+		else
+			curaddr = pmap_kextract(vaddr);
+
+
+		/*
+		 * Compute the segment size, and adjust counts.
+		 */
+		sgsize = PAGE_SIZE - ((u_long)curaddr & PAGE_MASK);
+		if (buflen < sgsize)
+			sgsize = buflen;
+
+		/*
+		 * Make sure we don't cross any boundaries.
+		 */
+		if (dmat->boundary > 0) {
+			baddr = (curaddr + dmat->boundary) & bmask;
+			if (sgsize > (baddr - curaddr))
+				sgsize = (baddr - curaddr);
+		}
+
+		if (map->pagesneeded != 0 && run_filter(dmat, curaddr))
+			panic("no bounce page support");
+		
+		/*
+		 * Insert chunk into a segment, coalescing with
+		 * previous segment if possible.
+		 */
+		if (first) {
+			segs[seg].ds_addr = curaddr;
+			segs[seg].ds_len = sgsize;
+			first = 0;
+		} else {
+			if (needbounce == 0 && curaddr == lastaddr &&
+			    (segs[seg].ds_len + sgsize) <= dmat->maxsegsz &&
+			    (dmat->boundary == 0 ||
+			     (segs[seg].ds_addr & bmask) == (curaddr & bmask)))
+				segs[seg].ds_len += sgsize;
+			else {
+				if (++seg >= dmat->nsegments)
+					break;
+				segs[seg].ds_addr = curaddr;
+				segs[seg].ds_len = sgsize;
+			}
+		}
+
+		lastaddr = curaddr + sgsize;
+		vaddr += sgsize;
+		buflen -= sgsize;
+	}
+
+	*segp = seg;
+	*lastaddrp = lastaddr;
+
+	/*
+	 * Did we fit?
+	 */
+	return (buflen != 0 ? EFBIG : 0); /* XXX better return value here? */
 }
 
 int
 bus_dmamap_load_mvec_sg(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0,
                         bus_dma_segment_t *segs, int *nsegs, int flags)
 {
-	int error;
-	struct mvec_sg_cb_arg cb_arg;
+	int error, i;
 
 	M_ASSERTPKTHDR(m0);
 	
@@ -452,51 +567,43 @@
 	*nsegs = 0;
 	error = 0;
 	if (m0->m_pkthdr.len <= dmat->maxsize) {
+		int first = 1;
+		bus_addr_t lastaddr = 0;
 		struct mbuf *m;
-		cb_arg.segs = segs;
+		
 		for (m = m0; m != NULL && error == 0; m = m->m_next) {
 			struct mbuf_vec *mv;
-			int count, first, i;
+			int count, firstcl;
 			if (!(m->m_len > 0))
 				continue;
 			
 			mv = mtomv(m);
 			count = mv->mv_count;
-			first = mv->mv_first;
+			firstcl = mv->mv_first;
 			KASSERT(count <= MAX_MBUF_IOV, ("count=%d too large", count));
-			for (i = first; i < count; i++) {
+			for (i = firstcl; i < count && error == 0; i++) {
 				void *data = mv->mv_vec[i].mi_base + mv->mv_vec[i].mi_offset;
-				int size = mv->mv_vec[i].mi_len;
+				int len = mv->mv_vec[i].mi_len;
 
-				if (size == 0)
+				if (len == 0)
 					continue;
-				DPRINTF("mapping data=%p size=%d\n", data, size); 
-				cb_arg.index = *nsegs;
-				error = bus_dmamap_load(dmat, map, 
-				    data, size, mvec_cb, &cb_arg, flags);
-				(*nsegs)++;
-				
-				if (*nsegs >= dmat->nsegments) {
-					DPRINTF("*nsegs=%d dmat->nsegments=%d index=%d\n",
-					    *nsegs, dmat->nsegments, cb_arg.index);
-					error = EFBIG;
-					goto err_out;
-				}
-				if (error || cb_arg.error)
-					goto err_out;
+				DPRINTF("mapping data=%p len=%d\n", data, len); 
+				error = _bus_dmamap_load_buffer(dmat, NULL, 
+				    data, len, NULL, flags, &lastaddr,
+				    segs, nsegs, first);
+				DPRINTF("%d: addr=0x%lx len=%ld\n", i, segs[i].ds_addr,
+				    segs[i].ds_len);
+				first = 0;
 			}
 		}
 	} else {
 		error = EINVAL;
 	}
+
+	(*nsegs)++;
+
 	CTR5(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d nsegs %d",
 	    __func__, dmat, dmat->flags, error, *nsegs);
 	return (error);
-
-err_out:
-	if (cb_arg.error)
-		return (cb_arg.error);
-	
-	return (error);
 }
 #endif /* !__sparc64__  && !__sun4v__ */

==== //depot/projects/mjexp/sys/sys/mbuf.h#8 (text+ko) ====

@@ -28,7 +28,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)mbuf.h	8.5 (Berkeley) 2/19/95
- * $FreeBSD: src/sys/sys/mbuf.h,v 1.210 2007/04/14 20:31:05 kmacy Exp $
+ * $FreeBSD: src/sys/sys/mbuf.h,v 1.211 2007/04/15 06:30:28 kmacy Exp $
  */
 
 #ifndef _SYS_MBUF_H_
@@ -341,9 +341,7 @@
 extern uma_zone_t	zone_jumbo16;
 extern uma_zone_t	zone_ext_refcnt;
 
-#ifndef MBUF_PACKET_ZONE_DISABLE
 static __inline struct mbuf	*m_getcl(int how, short type, int flags);
-#endif
 static __inline struct mbuf	*m_get(int how, short type);
 static __inline struct mbuf	*m_gethdr(int how, short type);
 static __inline struct mbuf	*m_getjcl(int how, short type, int flags,
@@ -453,7 +451,6 @@
 	return ((struct mbuf *)(uma_zalloc_arg(zone_mbuf, &args, how)));
 }
 
-#ifndef MBUF_PACKET_ZONE_DISABLE
 static __inline struct mbuf *
 m_getcl(int how, short type, int flags)
 {
@@ -463,9 +460,6 @@
 	args.type = type;
 	return ((struct mbuf *)(uma_zalloc_arg(zone_pack, &args, how)));
 }
-#else
-#define m_getcl(how, type, flags) m_getjcl(how, type, flags, MCLBYTES)
-#endif
 
 /*
  * m_getjcl() returns an mbuf with a cluster of the specified size attached.


More information about the p4-projects mailing list