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
This commit is contained in:
cognet 2009-02-09 18:03:31 +00:00
parent b885a20f24
commit 80c343b215
3 changed files with 18 additions and 3 deletions

View File

@ -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, int flags, bus_dmamap_t *mapp)
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, int flags, bus_dmamap_t *mapp)
error = 0;
}
}
bz->map_count++;
} else {
*mapp = NULL;
}
@ -457,6 +459,8 @@ bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
__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);

View File

@ -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, int flags, bus_dmamap_t *mapp)
*/
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, int flags, bus_dmamap_t *mapp)
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, bus_dmamap_t map)
__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);

View File

@ -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, int flags, bus_dmamap_t *mapp)
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, int flags, bus_dmamap_t *mapp)
error = 0;
}
}
bz->map_count++;
} else {
*mapp = NULL;
}
@ -470,6 +472,8 @@ bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map)
__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);