From owner-freebsd-current@FreeBSD.ORG Tue Jun 30 13:29:44 2009 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 53D93106566C for ; Tue, 30 Jun 2009 13:29:44 +0000 (UTC) (envelope-from kosmo@semihalf.com) Received: from smtp.semihalf.com (smtp.semihalf.com [213.17.239.109]) by mx1.freebsd.org (Postfix) with ESMTP id 712528FC16 for ; Tue, 30 Jun 2009 13:29:43 +0000 (UTC) (envelope-from kosmo@semihalf.com) Received: from [10.0.0.5] (cardhu.semihalf.com [213.17.239.108]) by smtp.semihalf.com (Postfix) with ESMTPSA id 5E2F4C3A96; Tue, 30 Jun 2009 15:28:25 +0200 (CEST) From: Piotr =?iso-8859-2?q?Zi=EAcik?= Organization: Semihalf To: Scott Long Date: Tue, 30 Jun 2009 15:29:42 +0200 User-Agent: PLD Linux KMail/1.9.10 References: <200906251329.35200.kosmo@semihalf.com> <200906260929.40709.kosmo@semihalf.com> <4A44D4AD.8010307@samsco.org> In-Reply-To: <4A44D4AD.8010307@samsco.org> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Message-Id: <200906301529.42195.kosmo@semihalf.com> Cc: freebsd-current@freebsd.org Subject: Re: [PATCH RFC]: Bus_dma eats all available memory X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 30 Jun 2009 13:29:44 -0000 =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