From 68aa5c006a8dcccba40b95f804362730250bf9e3 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Mon, 19 Apr 2004 13:37:43 +0000 Subject: [PATCH] In contrast to FreeBSD 4 and 5, our slab allocator does hand out cross-page allocations. This broke bus_dmamem_alloc, which depends on allocation of size < PAGE_SIZE to not cross pages. As a temporary workaround, bus_dmamem_alloc checks explicitly wether an allocation crossed page boundaries and retries the allocation with size rounded up to the next power-of-two. --- sys/i386/i386/busdma_machdep.c | 15 ++++++++++++++- sys/platform/pc32/i386/busdma_machdep.c | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/sys/i386/i386/busdma_machdep.c b/sys/i386/i386/busdma_machdep.c index 9867605e94..99baf27413 100644 --- a/sys/i386/i386/busdma_machdep.c +++ b/sys/i386/i386/busdma_machdep.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.16.2.2 2003/01/23 00:55:27 scottl Exp $ - * $DragonFly: src/sys/i386/i386/Attic/busdma_machdep.c,v 1.8 2004/04/02 18:16:45 joerg Exp $ + * $DragonFly: src/sys/i386/i386/Attic/busdma_machdep.c,v 1.9 2004/04/19 13:37:43 joerg Exp $ */ #include @@ -349,6 +349,19 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, if ((dmat->maxsize <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem)) { *vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags); + /* + * XXX Check wether the allocation crossed a page boundary + * and retry with power-of-2 alignment in that case. + */ + if ((((intptr_t)*vaddr) & PAGE_MASK) != + (((intptr_t)*vaddr + dmat->maxsize) & PAGE_MASK)) { + size_t size; + free(*vaddr, M_DEVBUF); + /* XXX check for overflow? */ + for (size = 1; size <= dmat->maxsize; size <<= 1) + ; + *vaddr = malloc(size, M_DEVBUF, mflags); + } } else { /* * XXX Use Contigmalloc until it is merged into this facility diff --git a/sys/platform/pc32/i386/busdma_machdep.c b/sys/platform/pc32/i386/busdma_machdep.c index 6c098af86d..7243401045 100644 --- a/sys/platform/pc32/i386/busdma_machdep.c +++ b/sys/platform/pc32/i386/busdma_machdep.c @@ -24,7 +24,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/i386/i386/busdma_machdep.c,v 1.16.2.2 2003/01/23 00:55:27 scottl Exp $ - * $DragonFly: src/sys/platform/pc32/i386/busdma_machdep.c,v 1.8 2004/04/02 18:16:45 joerg Exp $ + * $DragonFly: src/sys/platform/pc32/i386/busdma_machdep.c,v 1.9 2004/04/19 13:37:43 joerg Exp $ */ #include @@ -349,6 +349,19 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, if ((dmat->maxsize <= PAGE_SIZE) && dmat->lowaddr >= ptoa(Maxmem)) { *vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags); + /* + * XXX Check wether the allocation crossed a page boundary + * and retry with power-of-2 alignment in that case. + */ + if ((((intptr_t)*vaddr) & PAGE_MASK) != + (((intptr_t)*vaddr + dmat->maxsize) & PAGE_MASK)) { + size_t size; + free(*vaddr, M_DEVBUF); + /* XXX check for overflow? */ + for (size = 1; size <= dmat->maxsize; size <<= 1) + ; + *vaddr = malloc(size, M_DEVBUF, mflags); + } } else { /* * XXX Use Contigmalloc until it is merged into this facility -- 2.41.0