Friday 26 June 2009 16:01:17 Scott Long napisa³(a): > > Tags and maps should be allocated at driver initialization time, not > every time a request comes in. The problem here isn't the MAX() test, > it's that the MIN_ALLOC_COMP test is getting fooled because the tag > keeps on getting recycled. The correct fix is likely to move the flag > into the bounce zone object. But in general, you should not be > allocating and freeing tags and maps so often, they are meant to have a > long lifespan. > I have fixed my driver and updated patch for bus_dma. Could I ask you for review ? Patch was successfully tested on ARM. diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c index 775f142..dde9159 100644 --- a/sys/amd64/amd64/busdma_machdep.c +++ b/sys/amd64/amd64/busdma_machdep.c _at__at_ -84,6 +84,7 _at__at_ struct bounce_page { int busdma_swi_pending; +#define BZ_MIN_ALLOC_COMP 0x01 struct bounce_zone { STAILQ_ENTRY(bounce_zone) links; STAILQ_HEAD(bp_list, bounce_page) bounce_page_list; _at__at_ -98,6 +99,7 _at__at_ struct bounce_zone { bus_addr_t lowaddr; char zoneid[8]; char lowaddrid[20]; + int flags; struct sysctl_ctx_list sysctl_tree; struct sysctl_oid *sysctl_tree_top; }; _at__at_ -201,7 +203,6 _at__at_ dflt_lock(void *arg, bus_dma_lock_op_t op) } #define BUS_DMA_COULD_BOUNCE BUS_DMA_BUS3 -#define BUS_DMA_MIN_ALLOC_COMP BUS_DMA_BUS4 /* * Allocate a device specific dma_tag. */ _at__at_ -306,7 +307,7 _at__at_ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, error = ENOMEM; } /* Performed initial allocation */ - newtag->flags |= BUS_DMA_MIN_ALLOC_COMP; + bz->flags |= BZ_MIN_ALLOC_COMP; } if (error != 0) { _at__at_ -417,7 +418,7 _at__at_ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) maxpages = MAX_BPAGES; else maxpages = MIN(MAX_BPAGES, Maxmem -atop(dmat->lowaddr)); - if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0 + if ((bz->flags & BZ_MIN_ALLOC_COMP) == 0 || (bz->map_count > 0 && bz->total_bpages < maxpages)) { int pages; _at__at_ -427,9 +428,9 _at__at_ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) if (alloc_bounce_pages(dmat, pages) < pages) error = ENOMEM; - if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) { + if ((bz->flags & BZ_MIN_ALLOC_COMP) == 0) { if (error == 0) - dmat->flags |= BUS_DMA_MIN_ALLOC_COMP; + bz->flags |= BZ_MIN_ALLOC_COMP; } else { error = 0; } _at__at_ -994,6 +995,7 _at__at_ alloc_bounce_zone(bus_dma_tag_t dmat) bz->lowaddr = dmat->lowaddr; bz->alignment = MAX(dmat->alignment, PAGE_SIZE); bz->map_count = 0; + bz->flags = 0; snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount); busdma_zonecount++; snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr); diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c index a8b2de9..bbda08b 100644 --- a/sys/arm/arm/busdma_machdep.c +++ b/sys/arm/arm/busdma_machdep.c _at__at_ -62,7 +62,6 _at__at_ __FBSDID("$FreeBSD: src/sys/arm/arm/busdma_machdep.c,v 1.47 2009/04/23 20:24:19 #define MAX_BPAGES 64 #define BUS_DMA_COULD_BOUNCE BUS_DMA_BUS3 -#define BUS_DMA_MIN_ALLOC_COMP BUS_DMA_BUS4 struct bounce_zone; _at__at_ -104,6 +103,7 _at__at_ struct bounce_page { int busdma_swi_pending; +#define BZ_MIN_ALLOC_COMP 0x01 struct bounce_zone { STAILQ_ENTRY(bounce_zone) links; STAILQ_HEAD(bp_list, bounce_page) bounce_page_list; _at__at_ -118,6 +118,7 _at__at_ struct bounce_zone { bus_addr_t lowaddr; char zoneid[8]; char lowaddrid[20]; + int flags; struct sysctl_ctx_list sysctl_tree; struct sysctl_oid *sysctl_tree_top; }; _at__at_ -427,7 +428,7 _at__at_ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, error = ENOMEM; } /* Performed initial allocation */ - newtag->flags |= BUS_DMA_MIN_ALLOC_COMP; + bz->flags |= BZ_MIN_ALLOC_COMP; } else newtag->bounce_zone = NULL; if (error != 0) _at__at_ -523,7 +524,7 _at__at_ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) * basis up to a sane limit. */ maxpages = MAX_BPAGES; - if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0 + if ((bz->flags & BZ_MIN_ALLOC_COMP) == 0 || (bz->map_count > 0 && bz->total_bpages < maxpages)) { int pages; _at__at_ -533,9 +534,9 _at__at_ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) if (alloc_bounce_pages(dmat, pages) < pages) error = ENOMEM; - if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) { + if ((bz->flags & BZ_MIN_ALLOC_COMP) == 0) { if (error == 0) - dmat->flags |= BUS_DMA_MIN_ALLOC_COMP; + bz->flags |= BZ_MIN_ALLOC_COMP; } else { error = 0; } _at__at_ -1291,6 +1292,7 _at__at_ alloc_bounce_zone(bus_dma_tag_t dmat) bz->lowaddr = dmat->lowaddr; bz->alignment = MAX(dmat->alignment, PAGE_SIZE); bz->map_count = 0; + bz->flags = 0; snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount); busdma_zonecount++; snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr); diff --git a/sys/i386/i386/busdma_machdep.c b/sys/i386/i386/busdma_machdep.c index 50c1545..4ceaa05 100644 --- a/sys/i386/i386/busdma_machdep.c +++ b/sys/i386/i386/busdma_machdep.c _at__at_ -55,7 +55,6 _at__at_ __FBSDID("$FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.99 2009/04/23 20:24:1 #define MAX_BPAGES 512 #define BUS_DMA_COULD_BOUNCE BUS_DMA_BUS3 -#define BUS_DMA_MIN_ALLOC_COMP BUS_DMA_BUS4 struct bounce_zone; _at__at_ -89,6 +88,7 _at__at_ struct bounce_page { int busdma_swi_pending; +#define BZ_MIN_ALLOC_COMP 0x01 struct bounce_zone { STAILQ_ENTRY(bounce_zone) links; STAILQ_HEAD(bp_list, bounce_page) bounce_page_list; _at__at_ -103,6 +103,7 _at__at_ struct bounce_zone { bus_addr_t lowaddr; char zoneid[8]; char lowaddrid[20]; + int flags; struct sysctl_ctx_list sysctl_tree; struct sysctl_oid *sysctl_tree_top; }; _at__at_ -319,7 +320,7 _at__at_ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, error = ENOMEM; } /* Performed initial allocation */ - newtag->flags |= BUS_DMA_MIN_ALLOC_COMP; + bz->flags |= BZ_MIN_ALLOC_COMP; } if (error != 0) { _at__at_ -430,7 +431,7 _at__at_ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) maxpages = MAX_BPAGES; else maxpages = MIN(MAX_BPAGES, Maxmem -atop(dmat->lowaddr)); - if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0 + if ((bz->flags & BZ_MIN_ALLOC_COMP) == 0 || (bz->map_count > 0 && bz->total_bpages < maxpages)) { int pages; _at__at_ -440,9 +441,9 _at__at_ bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp) if (alloc_bounce_pages(dmat, pages) < pages) error = ENOMEM; - if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) == 0) { + if ((bz->flags & BZ_MIN_ALLOC_COMP) == 0) { if (error == 0) - dmat->flags |= BUS_DMA_MIN_ALLOC_COMP; + bz->flags |= BZ_MIN_ALLOC_COMP; } else { error = 0; } _at__at_ -1012,6 +1013,7 _at__at_ alloc_bounce_zone(bus_dma_tag_t dmat) bz->lowaddr = dmat->lowaddr; bz->alignment = MAX(dmat->alignment, PAGE_SIZE); bz->map_count = 0; + bz->flags = 0; snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount); busdma_zonecount++; snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr); -- Best Regards, Piotr ZiecikReceived on Tue Jun 30 2009 - 11:29:44 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:50 UTC