Index: sys/arch/arm/arm32/bus_dma.c =================================================================== RCS file: /cvsroot/src/sys/arch/arm/arm32/bus_dma.c,v retrieving revision 1.121 diff -u -p -r1.121 bus_dma.c --- sys/arch/arm/arm32/bus_dma.c 14 Mar 2020 18:08:38 -0000 1.121 +++ sys/arch/arm/arm32/bus_dma.c 26 Mar 2020 08:37:09 -0000 @@ -40,7 +40,9 @@ __KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v #include #include +#include #include +#include #include #include @@ -1384,6 +1386,8 @@ _bus_dmamem_map(bus_dma_tag_t t, bus_dma #endif size = round_page(size); +// if (size > PAGE_SIZE) +// fragmented = true; #ifdef PMAP_MAPSIZE1 if (size >= PMAP_MAPSIZE1) @@ -1599,8 +1603,10 @@ _bus_dmamem_alloc_range(bus_dma_tag_t t, { paddr_t curaddr, lastaddr; struct vm_page *m; + struct vm_page *hole = NULL; struct pglist mlist; int curseg, error; + bool fragment = false; KASSERTMSG(boundary == 0 || (boundary & (boundary - 1)) == 0, "invalid boundary %#lx", boundary); @@ -1612,6 +1618,10 @@ _bus_dmamem_alloc_range(bus_dma_tag_t t, /* Always round the size. */ size = round_page(size); + if (!cold && size > PAGE_SIZE) { + size += PAGE_SIZE; + fragment = true; + } /* * We accept boundaries < size, splitting in multiple segments @@ -1635,6 +1645,7 @@ _bus_dmamem_alloc_range(bus_dma_tag_t t, if (error) return error; + bool split = false; /* * Compute the location, size, and number of segments actually * returned by the VM code. @@ -1669,8 +1680,16 @@ _bus_dmamem_alloc_range(bus_dma_tag_t t, segs[curseg].ds_len = PAGE_SIZE; } lastaddr = curaddr; - } + if (fragment && !split && (cprng_fast32() & 1) == 0) { + m = TAILQ_NEXT(m, pageq.queue); + hole = m; + split = true; + } + } + if (fragment) { + printf("%s: hole %p\n", __func__, hole); + } *rsegs = curseg + 1; return 0;