[PATCH RFC]: Bus_dma eats all available memory

Piotr Zięcik kosmo at semihalf.com
Thu Jun 25 11:44:48 UTC 2009


Hi

While working on new driver for FreeBSD I have found a problem in bus_dma 
subsystem. Every time when bus_dmamap_create() is called on bus_dma tag
using bounce zone, at least 1 page in bounce zone is allocated. This causes 
eating of all avaible memory by bounce zone. Problem affects i386, amd64 and 
arm.

This behaviour was introduced by 
http://svn.freebsd.org/viewvc/base?view=revision&revision=143449 fixing
another error in bus_dma. My patch, attached to this mail, fixes the problem 
by allocating new pages only when bounce zone is too small.

Patch was sucessfuly tested on arm, but I am not sure that my change does
not have any side effects, so if you see any please comment.

Patch:
diff --git a/sys/amd64/amd64/busdma_machdep.c 
b/sys/amd64/amd64/busdma_machdep.c
index 775f142..083cbae 100644
--- a/sys/amd64/amd64/busdma_machdep.c
+++ b/sys/amd64/amd64/busdma_machdep.c
@@ -423,7 +423,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, 
bus_dmamap_t *mapp)

                        pages = MAX(atop(dmat->maxsize), 1);
                        pages = MIN(maxpages - bz->total_bpages, pages);
-                       pages = MAX(pages, 1);
+                       pages = MAX(pages, 0);
                        if (alloc_bounce_pages(dmat, pages) < pages)
                                error = ENOMEM;

diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
index a8b2de9..ef1afad 100644
--- a/sys/arm/arm/busdma_machdep.c
+++ b/sys/arm/arm/busdma_machdep.c
@@ -529,7 +529,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, 
bus_dmamap_t *mapp)

                        pages = MAX(atop(dmat->maxsize), 1);
                        pages = MIN(maxpages - bz->total_bpages, pages);
-                       pages = MAX(pages, 1);
+                       pages = MAX(pages, 0);
                        if (alloc_bounce_pages(dmat, pages) < pages)
                                error = ENOMEM;

diff --git a/sys/i386/i386/busdma_machdep.c b/sys/i386/i386/busdma_machdep.c
index 50c1545..f31d98f 100644
--- a/sys/i386/i386/busdma_machdep.c
+++ b/sys/i386/i386/busdma_machdep.c
@@ -436,7 +436,7 @@ bus_dmamap_create(bus_dma_tag_t dmat, int flags, 
bus_dmamap_t *mapp)

                        pages = MAX(atop(dmat->maxsize), 1);
                        pages = MIN(maxpages - bz->total_bpages, pages);
-                       pages = MAX(pages, 1);
+                       pages = MAX(pages, 0);
                        if (alloc_bounce_pages(dmat, pages) < pages)

-- 
Best Regards,
Piotr Ziecik


More information about the freebsd-current mailing list