[PATCH RFC]: Bus_dma eats all available memory

From: Piotr Ziêcik <kosmo_at_semihalf.com>
Date: Thu, 25 Jun 2009 13:29:35 +0200
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
_at__at_ -423,7 +423,7 _at__at_ 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
_at__at_ -529,7 +529,7 _at__at_ 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
_at__at_ -436,7 +436,7 _at__at_ 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
Received on Thu Jun 25 2009 - 09:44:48 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:50 UTC