svn commit: r188403 - in head/sys: amd64/amd64 arm/arm i386/i386

Olivier Houchard cognet at FreeBSD.org
Mon Feb 9 10:03:33 PST 2009


Author: cognet
Date: Mon Feb  9 18:03:31 2009
New Revision: 188403
URL: http://svn.freebsd.org/changeset/base/188403

Log:
  The bounce zone sees its page number increased if multiple dma maps use it in
  the same dma tag. However, it can happen multiple dma tags share the same
  bounce zone too, so add a per-bounce zone map counter, and check it instead of
  the dma tag map counter, to know if we have to alloc more pages.
  
  Reported by:	miwi
  Reviewed by:	scottl

Modified:
  head/sys/amd64/amd64/busdma_machdep.c
  head/sys/arm/arm/busdma_machdep.c
  head/sys/i386/i386/busdma_machdep.c

Modified: head/sys/amd64/amd64/busdma_machdep.c
==============================================================================
--- head/sys/amd64/amd64/busdma_machdep.c	Mon Feb  9 18:01:54 2009	(r188402)
+++ head/sys/amd64/amd64/busdma_machdep.c	Mon Feb  9 18:03:31 2009	(r188403)
@@ -93,6 +93,7 @@ struct bounce_zone {
 	int		active_bpages;
 	int		total_bounced;
 	int		total_deferred;
+	int		map_count;
 	bus_size_t	alignment;
 	bus_size_t	boundary;
 	bus_addr_t	lowaddr;
@@ -418,7 +419,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, in
 		else
 			maxpages = MIN(MAX_BPAGES, Maxmem -atop(dmat->lowaddr));
 		if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0
-		 || (dmat->map_count > 0 && bz->total_bpages < maxpages)) {
+		 || (bz->map_count > 0 && bz->total_bpages < maxpages)) {
 			int pages;
 
 			pages = MAX(atop(dmat->maxsize), 1);
@@ -434,6 +435,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, in
 				error = 0;
 			}
 		}
+		bz->map_count++;
 	} else {
 		*mapp = NULL;
 	}
@@ -457,6 +459,8 @@ bus_dmamap_destroy(bus_dma_tag_t dmat, b
 			    __func__, dmat, EBUSY);
 			return (EBUSY);
 		}
+		if (dmat->bounce_zone)
+			dmat->bounce_zone->map_count--;
 		free(map, M_DEVBUF);
 	}
 	dmat->map_count--;
@@ -989,6 +993,7 @@ alloc_bounce_zone(bus_dma_tag_t dmat)
 	bz->lowaddr = dmat->lowaddr;
 	bz->alignment = dmat->alignment;
 	bz->boundary = dmat->boundary;
+	bz->map_count = 0;
 	snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount);
 	busdma_zonecount++;
 	snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr);

Modified: head/sys/arm/arm/busdma_machdep.c
==============================================================================
--- head/sys/arm/arm/busdma_machdep.c	Mon Feb  9 18:01:54 2009	(r188402)
+++ head/sys/arm/arm/busdma_machdep.c	Mon Feb  9 18:03:31 2009	(r188403)
@@ -112,6 +112,7 @@ struct bounce_zone {
 	int		active_bpages;
 	int		total_bounced;
 	int		total_deferred;
+	int		map_count;
 	bus_size_t	alignment;
 	bus_size_t	boundary;
 	bus_addr_t	lowaddr;
@@ -523,7 +524,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, in
 		 */
 		maxpages = MAX_BPAGES;
 		if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0
-		 || (dmat->map_count > 0 && bz->total_bpages < maxpages)) {
+		 || (bz->map_count > 0 && bz->total_bpages < maxpages)) {
 			int pages;
 
 			pages = MAX(atop(dmat->maxsize), 1);
@@ -539,6 +540,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, in
 				error = 0;
 			}
 		}
+		bz->map_count++;
 	}
 	CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
 	    __func__, dmat, dmat->flags, error);
@@ -560,6 +562,8 @@ bus_dmamap_destroy(bus_dma_tag_t dmat, b
 		    __func__, dmat, EBUSY);
 		return (EBUSY);
 	}
+	if (dmat->bounce_zone)
+		dmat->bounce_zone->map_count--;
         dmat->map_count--;
 	CTR2(KTR_BUSDMA, "%s: tag %p error 0", __func__, dmat);
         return (0);
@@ -1277,6 +1281,7 @@ alloc_bounce_zone(bus_dma_tag_t dmat)
 	bz->lowaddr = dmat->lowaddr;
 	bz->alignment = dmat->alignment;
 	bz->boundary = dmat->boundary;
+	bz->map_count = 0;
 	snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount);
 	busdma_zonecount++;
 	snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr);

Modified: head/sys/i386/i386/busdma_machdep.c
==============================================================================
--- head/sys/i386/i386/busdma_machdep.c	Mon Feb  9 18:01:54 2009	(r188402)
+++ head/sys/i386/i386/busdma_machdep.c	Mon Feb  9 18:03:31 2009	(r188403)
@@ -98,6 +98,7 @@ struct bounce_zone {
 	int		active_bpages;
 	int		total_bounced;
 	int		total_deferred;
+	int		map_count;
 	bus_size_t	alignment;
 	bus_size_t	boundary;
 	bus_addr_t	lowaddr;
@@ -431,7 +432,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, in
 		else
 			maxpages = MIN(MAX_BPAGES, Maxmem -atop(dmat->lowaddr));
 		if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0
-		 || (dmat->map_count > 0 && bz->total_bpages < maxpages)) {
+		 || (bz->map_count > 0 && bz->total_bpages < maxpages)) {
 			int pages;
 
 			pages = MAX(atop(dmat->maxsize), 1);
@@ -447,6 +448,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, in
 				error = 0;
 			}
 		}
+		bz->map_count++;
 	} else {
 		*mapp = NULL;
 	}
@@ -470,6 +472,8 @@ bus_dmamap_destroy(bus_dma_tag_t dmat, b
 			    __func__, dmat, EBUSY);
 			return (EBUSY);
 		}
+		if (dmat->bounce_zone)
+			dmat->bounce_zone->map_count--;
 		free(map, M_DEVBUF);
 	}
 	dmat->map_count--;
@@ -1007,6 +1011,7 @@ alloc_bounce_zone(bus_dma_tag_t dmat)
 	bz->lowaddr = dmat->lowaddr;
 	bz->alignment = dmat->alignment;
 	bz->boundary = dmat->boundary;
+	bz->map_count = 0;
 	snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount);
 	busdma_zonecount++;
 	snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr);


More information about the svn-src-head mailing list