Skip site navigation (1)Skip section navigation (2)
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>