Date: Tue, 30 Jun 2009 15:29:42 +0200 From: Piotr =?iso-8859-2?q?Zi=EAcik?= <kosmo@semihalf.com> To: Scott Long <scottl@samsco.org> Cc: freebsd-current@freebsd.org Subject: Re: [PATCH RFC]: Bus_dma eats all available memory Message-ID: <200906301529.42195.kosmo@semihalf.com> In-Reply-To: <4A44D4AD.8010307@samsco.org> References: <200906251329.35200.kosmo@semihalf.com> <200906260929.40709.kosmo@semihalf.com> <4A44D4AD.8010307@samsco.org>
next in thread | previous in thread | raw e-mail | index | archive | help
=46riday 26 June 2009 16:01:17 Scott Long napisa=B3(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=20 review ? Patch was successfully tested on ARM. diff --git a/sys/amd64/amd64/busdma_machdep.c=20 b/sys/amd64/amd64/busdma_machdep.c index 775f142..dde9159 100644 =2D-- a/sys/amd64/amd64/busdma_machdep.c +++ b/sys/amd64/amd64/busdma_machdep.c @@ -84,6 +84,7 @@ struct bounce_page { =20 int busdma_swi_pending; =20 +#define BZ_MIN_ALLOC_COMP 0x01 struct bounce_zone { STAILQ_ENTRY(bounce_zone) links; STAILQ_HEAD(bp_list, bounce_page) bounce_page_list; @@ -98,6 +99,7 @@ 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; }; @@ -201,7 +203,6 @@ dflt_lock(void *arg, bus_dma_lock_op_t op) } =20 #define BUS_DMA_COULD_BOUNCE BUS_DMA_BUS3 =2D#define BUS_DMA_MIN_ALLOC_COMP BUS_DMA_BUS4 /* * Allocate a device specific dma_tag. */ @@ -306,7 +307,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t=20 alignment, error =3D ENOMEM; } /* Performed initial allocation */ =2D newtag->flags |=3D BUS_DMA_MIN_ALLOC_COMP; + bz->flags |=3D BZ_MIN_ALLOC_COMP; } =09 if (error !=3D 0) { @@ -417,7 +418,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags,=20 bus_dmamap_t *mapp) maxpages =3D MAX_BPAGES; else maxpages =3D MIN(MAX_BPAGES, Maxmem -atop(dmat->lowaddr)); =2D if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) =3D=3D 0 + if ((bz->flags & BZ_MIN_ALLOC_COMP) =3D=3D 0 || (bz->map_count > 0 && bz->total_bpages < maxpages)) { int pages; =20 @@ -427,9 +428,9 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags,=20 bus_dmamap_t *mapp) if (alloc_bounce_pages(dmat, pages) < pages) error =3D ENOMEM; =20 =2D if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) =3D=3D 0) { + if ((bz->flags & BZ_MIN_ALLOC_COMP) =3D=3D 0) { if (error =3D=3D 0) =2D dmat->flags |=3D BUS_DMA_MIN_ALLOC_COMP; + bz->flags |=3D BZ_MIN_ALLOC_COMP; } else { error =3D 0; } @@ -994,6 +995,7 @@ alloc_bounce_zone(bus_dma_tag_t dmat) bz->lowaddr =3D dmat->lowaddr; bz->alignment =3D MAX(dmat->alignment, PAGE_SIZE); bz->map_count =3D 0; + bz->flags =3D 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 =2D-- a/sys/arm/arm/busdma_machdep.c +++ b/sys/arm/arm/busdma_machdep.c @@ -62,7 +62,6 @@ __FBSDID("$FreeBSD: src/sys/arm/arm/busdma_machdep.c,v 1.= 47=20 2009/04/23 20:24:19 =20 #define MAX_BPAGES 64 #define BUS_DMA_COULD_BOUNCE BUS_DMA_BUS3 =2D#define BUS_DMA_MIN_ALLOC_COMP BUS_DMA_BUS4 =20 struct bounce_zone; =20 @@ -104,6 +103,7 @@ struct bounce_page { =20 int busdma_swi_pending; =20 +#define BZ_MIN_ALLOC_COMP 0x01 struct bounce_zone { STAILQ_ENTRY(bounce_zone) links; STAILQ_HEAD(bp_list, bounce_page) bounce_page_list; @@ -118,6 +118,7 @@ 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; }; @@ -427,7 +428,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t=20 alignment, error =3D ENOMEM; } /* Performed initial allocation */ =2D newtag->flags |=3D BUS_DMA_MIN_ALLOC_COMP; + bz->flags |=3D BZ_MIN_ALLOC_COMP; } else newtag->bounce_zone =3D NULL; if (error !=3D 0) @@ -523,7 +524,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags,=20 bus_dmamap_t *mapp) * basis up to a sane limit. */ maxpages =3D MAX_BPAGES; =2D if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) =3D=3D 0 + if ((bz->flags & BZ_MIN_ALLOC_COMP) =3D=3D 0 || (bz->map_count > 0 && bz->total_bpages < maxpages)) { int pages; =20 @@ -533,9 +534,9 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags,=20 bus_dmamap_t *mapp) if (alloc_bounce_pages(dmat, pages) < pages) error =3D ENOMEM; =20 =2D if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) =3D=3D 0) { + if ((bz->flags & BZ_MIN_ALLOC_COMP) =3D=3D 0) { if (error =3D=3D 0) =2D dmat->flags |=3D BUS_DMA_MIN_ALLOC_COMP; + bz->flags |=3D BZ_MIN_ALLOC_COMP; } else { error =3D 0; } @@ -1291,6 +1292,7 @@ alloc_bounce_zone(bus_dma_tag_t dmat) bz->lowaddr =3D dmat->lowaddr; bz->alignment =3D MAX(dmat->alignment, PAGE_SIZE); bz->map_count =3D 0; + bz->flags =3D 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 =2D-- a/sys/i386/i386/busdma_machdep.c +++ b/sys/i386/i386/busdma_machdep.c @@ -55,7 +55,6 @@ __FBSDID("$FreeBSD: src/sys/i386/i386/busdma_machdep.c,v= =20 1.99 2009/04/23 20:24:1 =20 #define MAX_BPAGES 512 #define BUS_DMA_COULD_BOUNCE BUS_DMA_BUS3 =2D#define BUS_DMA_MIN_ALLOC_COMP BUS_DMA_BUS4 =20 struct bounce_zone; =20 @@ -89,6 +88,7 @@ struct bounce_page { =20 int busdma_swi_pending; =20 +#define BZ_MIN_ALLOC_COMP 0x01 struct bounce_zone { STAILQ_ENTRY(bounce_zone) links; STAILQ_HEAD(bp_list, bounce_page) bounce_page_list; @@ -103,6 +103,7 @@ 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; }; @@ -319,7 +320,7 @@ bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t=20 alignment, error =3D ENOMEM; } /* Performed initial allocation */ =2D newtag->flags |=3D BUS_DMA_MIN_ALLOC_COMP; + bz->flags |=3D BZ_MIN_ALLOC_COMP; } =09 if (error !=3D 0) { @@ -430,7 +431,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags,=20 bus_dmamap_t *mapp) maxpages =3D MAX_BPAGES; else maxpages =3D MIN(MAX_BPAGES, Maxmem -atop(dmat->lowaddr)); =2D if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) =3D=3D 0 + if ((bz->flags & BZ_MIN_ALLOC_COMP) =3D=3D 0 || (bz->map_count > 0 && bz->total_bpages < maxpages)) { int pages; =20 @@ -440,9 +441,9 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags,=20 bus_dmamap_t *mapp) if (alloc_bounce_pages(dmat, pages) < pages) error =3D ENOMEM; =20 =2D if ((dmat->flags & BUS_DMA_MIN_ALLOC_COMP) =3D=3D 0) { + if ((bz->flags & BZ_MIN_ALLOC_COMP) =3D=3D 0) { if (error =3D=3D 0) =2D dmat->flags |=3D BUS_DMA_MIN_ALLOC_COMP; + bz->flags |=3D BZ_MIN_ALLOC_COMP; } else { error =3D 0; } @@ -1012,6 +1013,7 @@ alloc_bounce_zone(bus_dma_tag_t dmat) bz->lowaddr =3D dmat->lowaddr; bz->alignment =3D MAX(dmat->alignment, PAGE_SIZE); bz->map_count =3D 0; + bz->flags =3D 0; snprintf(bz->zoneid, 8, "zone%d", busdma_zonecount); busdma_zonecount++; snprintf(bz->lowaddrid, 18, "%#jx", (uintmax_t)bz->lowaddr); =2D-=20 Best Regards, Piotr Ziecik
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906301529.42195.kosmo>