From 10395e071456c67ef7d8ae06e37c064382c7ec5d Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 23 Apr 2009 20:24:19 +0000 Subject: [PATCH] Reduce the number of bounce zones (and thus the number of bounce pages used in some cases): - Ignore DMA tag boundaries when allocating bounce pages. The boundaries don't determine whether or not parts of a DMA request bounce. Instead, they are just used to carve up segments. - Allow tags with sub-page alignment to share bounce pages since bounce pages are always page aligned. Reviewed by: scottl (amd64) MFC after: 1 month --- sys/amd64/amd64/busdma_machdep.c | 10 ++-------- sys/arm/arm/busdma_machdep.c | 16 +++++----------- sys/i386/i386/busdma_machdep.c | 10 ++-------- 3 files changed, 9 insertions(+), 27 deletions(-) diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c index d4031519dec4..3197d154960c 100644 --- a/sys/amd64/amd64/busdma_machdep.c +++ b/sys/amd64/amd64/busdma_machdep.c @@ -95,7 +95,6 @@ struct bounce_zone { int total_deferred; int map_count; bus_size_t alignment; - bus_size_t boundary; bus_addr_t lowaddr; char zoneid[8]; char lowaddrid[20]; @@ -978,7 +977,6 @@ alloc_bounce_zone(bus_dma_tag_t dmat) /* Check to see if we already have a suitable zone */ STAILQ_FOREACH(bz, &bounce_zone_list, links) { if ((dmat->alignment <= bz->alignment) - && (dmat->boundary <= bz->boundary) && (dmat->lowaddr >= bz->lowaddr)) { dmat->bounce_zone = bz; return (0); @@ -994,8 +992,7 @@ alloc_bounce_zone(bus_dma_tag_t dmat) bz->reserved_bpages = 0; bz->active_bpages = 0; bz->lowaddr = dmat->lowaddr; - bz->alignment = dmat->alignment; - bz->boundary = dmat->boundary; + bz->alignment = MAX(dmat->alignment, PAGE_SIZE); bz->map_count = 0; snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount); busdma_zonecount++; @@ -1042,9 +1039,6 @@ alloc_bounce_zone(bus_dma_tag_t dmat) SYSCTL_ADD_INT(busdma_sysctl_tree(bz), SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, "alignment", CTLFLAG_RD, &bz->alignment, 0, ""); - SYSCTL_ADD_INT(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "boundary", CTLFLAG_RD, &bz->boundary, 0, ""); return (0); } @@ -1069,7 +1063,7 @@ alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages) M_NOWAIT, 0ul, bz->lowaddr, PAGE_SIZE, - bz->boundary); + 0); if (bpage->vaddr == 0) { free(bpage, M_DEVBUF); break; diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c index fb3afeeac5f0..f35840efc83b 100644 --- a/sys/arm/arm/busdma_machdep.c +++ b/sys/arm/arm/busdma_machdep.c @@ -114,7 +114,6 @@ struct bounce_zone { int total_deferred; int map_count; bus_size_t alignment; - bus_size_t boundary; bus_addr_t lowaddr; char zoneid[8]; char lowaddrid[20]; @@ -689,10 +688,10 @@ _bus_dmamap_count_pages(bus_dma_tag_t dmat, bus_dmamap_t map, pmap_t pmap, vendaddr = (vm_offset_t)buf + buflen; while (vaddr < vendaddr) { - if (pmap != NULL) - paddr = pmap_extract(pmap, vaddr); - else + if (__predict_true(pmap == pmap_kernel())) paddr = pmap_kextract(vaddr); + else + paddr = pmap_extract(pmap, vaddr); if (((dmat->flags & BUS_DMA_COULD_BOUNCE) != 0) && run_filter(dmat, paddr) != 0) map->pagesneeded++; @@ -1267,7 +1266,6 @@ alloc_bounce_zone(bus_dma_tag_t dmat) /* Check to see if we already have a suitable zone */ STAILQ_FOREACH(bz, &bounce_zone_list, links) { if ((dmat->alignment <= bz->alignment) - && (dmat->boundary <= bz->boundary) && (dmat->lowaddr >= bz->lowaddr)) { dmat->bounce_zone = bz; return (0); @@ -1283,8 +1281,7 @@ alloc_bounce_zone(bus_dma_tag_t dmat) bz->reserved_bpages = 0; bz->active_bpages = 0; bz->lowaddr = dmat->lowaddr; - bz->alignment = dmat->alignment; - bz->boundary = dmat->boundary; + bz->alignment = MAX(dmat->alignment, PAGE_SIZE); bz->map_count = 0; snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount); busdma_zonecount++; @@ -1331,9 +1328,6 @@ alloc_bounce_zone(bus_dma_tag_t dmat) SYSCTL_ADD_INT(busdma_sysctl_tree(bz), SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, "alignment", CTLFLAG_RD, &bz->alignment, 0, ""); - SYSCTL_ADD_INT(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "boundary", CTLFLAG_RD, &bz->boundary, 0, ""); return (0); } @@ -1358,7 +1352,7 @@ alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages) M_NOWAIT, 0ul, bz->lowaddr, PAGE_SIZE, - bz->boundary); + 0); if (bpage->vaddr == 0) { free(bpage, M_DEVBUF); break; diff --git a/sys/i386/i386/busdma_machdep.c b/sys/i386/i386/busdma_machdep.c index 921cb0b90f3f..e59add7a8e37 100644 --- a/sys/i386/i386/busdma_machdep.c +++ b/sys/i386/i386/busdma_machdep.c @@ -100,7 +100,6 @@ struct bounce_zone { int total_deferred; int map_count; bus_size_t alignment; - bus_size_t boundary; bus_addr_t lowaddr; char zoneid[8]; char lowaddrid[20]; @@ -996,7 +995,6 @@ alloc_bounce_zone(bus_dma_tag_t dmat) /* Check to see if we already have a suitable zone */ STAILQ_FOREACH(bz, &bounce_zone_list, links) { if ((dmat->alignment <= bz->alignment) - && (dmat->boundary <= bz->boundary) && (dmat->lowaddr >= bz->lowaddr)) { dmat->bounce_zone = bz; return (0); @@ -1012,8 +1010,7 @@ alloc_bounce_zone(bus_dma_tag_t dmat) bz->reserved_bpages = 0; bz->active_bpages = 0; bz->lowaddr = dmat->lowaddr; - bz->alignment = dmat->alignment; - bz->boundary = dmat->boundary; + bz->alignment = MAX(dmat->alignment, PAGE_SIZE); bz->map_count = 0; snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount); busdma_zonecount++; @@ -1060,9 +1057,6 @@ alloc_bounce_zone(bus_dma_tag_t dmat) SYSCTL_ADD_INT(busdma_sysctl_tree(bz), SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, "alignment", CTLFLAG_RD, &bz->alignment, 0, ""); - SYSCTL_ADD_INT(busdma_sysctl_tree(bz), - SYSCTL_CHILDREN(busdma_sysctl_tree_top(bz)), OID_AUTO, - "boundary", CTLFLAG_RD, &bz->boundary, 0, ""); return (0); } @@ -1087,7 +1081,7 @@ alloc_bounce_pages(bus_dma_tag_t dmat, u_int numpages) M_NOWAIT, 0ul, bz->lowaddr, PAGE_SIZE, - bz->boundary); + 0); if (bpage->vaddr == 0) { free(bpage, M_DEVBUF); break;