Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 2 Feb 2015 11:32:16 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r278074 - in head/sys: conf dev/usb
Message-ID:  <201502021132.t12BWGae016753@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Mon Feb  2 11:32:15 2015
New Revision: 278074
URL: https://svnweb.freebsd.org/changeset/base/278074

Log:
  Optimise allocation of USB DMA structures. By default don't double map
  allocations if only one element should be allocated per page
  cache. Make one allocation per element compile time configurable. Fix
  a comment while at it.
  
  Suggested by:	ian @
  MFC after:	1 week

Modified:
  head/sys/conf/options
  head/sys/dev/usb/usb_transfer.c

Modified: head/sys/conf/options
==============================================================================
--- head/sys/conf/options	Mon Feb  2 11:26:52 2015	(r278073)
+++ head/sys/conf/options	Mon Feb  2 11:32:15 2015	(r278074)
@@ -651,6 +651,7 @@ USB_HOST_ALIGN		opt_usb.h
 USB_REQ_DEBUG		opt_usb.h
 USB_TEMPLATE		opt_usb.h
 USB_VERBOSE		opt_usb.h
+USB_DMA_SINGLE_ALLOC	opt_usb.h
 USB_EHCI_BIG_ENDIAN_DESC	opt_usb.h
 U3G_DEBUG		opt_u3g.h
 UKBD_DFLT_KEYMAP	opt_ukbd.h

Modified: head/sys/dev/usb/usb_transfer.c
==============================================================================
--- head/sys/dev/usb/usb_transfer.c	Mon Feb  2 11:26:52 2015	(r278073)
+++ head/sys/dev/usb/usb_transfer.c	Mon Feb  2 11:32:15 2015	(r278074)
@@ -237,7 +237,11 @@ usbd_transfer_setup_sub_malloc(struct us
 		n_obj = 1;
 	} else {
 		/* compute number of objects per page */
+#ifdef USB_DMA_SINGLE_ALLOC
+		n_obj = 1;
+#else
 		n_obj = (USB_PAGE_SIZE / size);
+#endif
 		/*
 		 * Compute number of DMA chunks, rounded up
 		 * to nearest one:
@@ -273,15 +277,33 @@ usbd_transfer_setup_sub_malloc(struct us
 		    &parm->curr_xfer->xroot->dma_parent_tag;
 	}
 
-	if (ppc) {
-		*ppc = parm->xfer_page_cache_ptr;
+	if (ppc != NULL) {
+		if (n_obj != 1)
+			*ppc = parm->xfer_page_cache_ptr;
+		else
+			*ppc = parm->dma_page_cache_ptr;
 	}
 	r = count;			/* set remainder count */
 	z = n_obj * size;		/* set allocation size */
 	pc = parm->xfer_page_cache_ptr;
 	pg = parm->dma_page_ptr;
 
-	for (x = 0; x != n_dma_pc; x++) {
+	if (n_obj == 1) {
+	    /*
+	     * Avoid mapping memory twice if only a single object
+	     * should be allocated per page cache:
+	     */
+	    for (x = 0; x != n_dma_pc; x++) {
+		if (usb_pc_alloc_mem(parm->dma_page_cache_ptr,
+		    pg, z, align)) {
+			return (1);	/* failure */
+		}
+		/* Make room for one DMA page cache and "n_dma_pg" pages */
+		parm->dma_page_cache_ptr++;
+		pg += n_dma_pg;
+	    }
+	} else {
+	    for (x = 0; x != n_dma_pc; x++) {
 
 		if (r < n_obj) {
 			/* compute last remainder */
@@ -294,7 +316,7 @@ usbd_transfer_setup_sub_malloc(struct us
 		}
 		/* Set beginning of current buffer */
 		buf = parm->dma_page_cache_ptr->buffer;
-		/* Make room for one DMA page cache and one page */
+		/* Make room for one DMA page cache and "n_dma_pg" pages */
 		parm->dma_page_cache_ptr++;
 		pg += n_dma_pg;
 
@@ -314,6 +336,7 @@ usbd_transfer_setup_sub_malloc(struct us
 			}
 			mtx_unlock(pc->tag_parent->mtx);
 		}
+	    }
 	}
 
 	parm->xfer_page_cache_ptr = pc;



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