summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2016-01-24 19:21:53 +0000
committerian <ian@FreeBSD.org>2016-01-24 19:21:53 +0000
commit6e826779c72ba605eb445362d8558a6233a9a7c8 (patch)
treef942af14f01fe26be62f9e0538420a01c60aab8e
parent89f44178f6f559f38929d5240797dcbdb21a857b (diff)
downloadFreeBSD-src-6e826779c72ba605eb445362d8558a6233a9a7c8.zip
FreeBSD-src-6e826779c72ba605eb445362d8558a6233a9a7c8.tar.gz
MFC r289618, r290316:
Fix printf format to allow for bus_size_t not being u_long on all platforms. Fix an alignment check that is wrong in half the busdma implementations. This will enable the elimination of a workaround in the USB driver that artifically allocates buffers twice as big as they need to be (which actually saves memory for very small buffers on the buggy platforms). When deciding how to allocate a dma buffer, armv4, armv6, mips, and x86/iommu all correctly check for the tag alignment <= maxsize as enabling simple uma/malloc based allocation. Powerpc, sparc64, x86/bounce, and arm64/bounce were all checking for alignment < maxsize; on those platforms when alignment was equal to the max size it would fall back to page-based allocators even for very small buffers. This change makes all platforms use the <= check. It should be noted that on all platforms other than arm[v6] and mips, this check is relying on undocumented behavior in malloc(9) that if you allocate a block of a given size it will be aligned to the next larger power-of-2 boundary. There is nothing in the malloc(9) man page that makes that explicit promise (but the busdma code has been relying on this behavior all along so I guess it works). Arm and mips code uses the allocator in kern/subr_busdma_buffalloc.c, which does explicitly implement this promise about size and alignment. Other platforms probably should switch to the aligned allocator.
-rw-r--r--sys/kern/subr_busdma_bufalloc.c4
-rw-r--r--sys/powerpc/powerpc/busdma_machdep.c4
-rw-r--r--sys/sparc64/sparc64/bus_machdep.c4
-rw-r--r--sys/x86/x86/busdma_bounce.c4
4 files changed, 8 insertions, 8 deletions
diff --git a/sys/kern/subr_busdma_bufalloc.c b/sys/kern/subr_busdma_bufalloc.c
index b0b1ba8..c8980e1 100644
--- a/sys/kern/subr_busdma_bufalloc.c
+++ b/sys/kern/subr_busdma_bufalloc.c
@@ -94,8 +94,8 @@ busdma_bufalloc_create(const char *name, bus_size_t minimum_alignment,
for (i = 0, bz = ba->buf_zones, cursize = ba->min_size;
i < nitems(ba->buf_zones) && cursize <= MAX_ZONE_BUFSIZE;
++i, ++bz, cursize <<= 1) {
- snprintf(bz->name, sizeof(bz->name), "dma %.10s %lu",
- name, cursize);
+ snprintf(bz->name, sizeof(bz->name), "dma %.10s %ju",
+ name, (uintmax_t)cursize);
bz->size = cursize;
bz->umazone = uma_zcreate(bz->name, bz->size,
NULL, NULL, NULL, NULL, bz->size - 1, zcreate_flags);
diff --git a/sys/powerpc/powerpc/busdma_machdep.c b/sys/powerpc/powerpc/busdma_machdep.c
index 9ea51ce..1e57d92 100644
--- a/sys/powerpc/powerpc/busdma_machdep.c
+++ b/sys/powerpc/powerpc/busdma_machdep.c
@@ -514,14 +514,14 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
/*
* XXX:
- * (dmat->alignment < dmat->maxsize) is just a quick hack; the exact
+ * (dmat->alignment <= dmat->maxsize) is just a quick hack; the exact
* alignment guarantees of malloc need to be nailed down, and the
* code below should be rewritten to take that into account.
*
* In the meantime, we'll warn the user if malloc gets it wrong.
*/
if ((dmat->maxsize <= PAGE_SIZE) &&
- (dmat->alignment < dmat->maxsize) &&
+ (dmat->alignment <= dmat->maxsize) &&
dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem) &&
attr == VM_MEMATTR_DEFAULT) {
*vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags);
diff --git a/sys/sparc64/sparc64/bus_machdep.c b/sys/sparc64/sparc64/bus_machdep.c
index 415f43d..fcac25a 100644
--- a/sys/sparc64/sparc64/bus_machdep.c
+++ b/sys/sparc64/sparc64/bus_machdep.c
@@ -521,14 +521,14 @@ nexus_dmamem_alloc(bus_dma_tag_t dmat, void **vaddr, int flags,
/*
* XXX:
- * (dmat->dt_alignment < dmat->dt_maxsize) is just a quick hack; the
+ * (dmat->dt_alignment <= dmat->dt_maxsize) is just a quick hack; the
* exact alignment guarantees of malloc need to be nailed down, and
* the code below should be rewritten to take that into account.
*
* In the meantime, we'll warn the user if malloc gets it wrong.
*/
if (dmat->dt_maxsize <= PAGE_SIZE &&
- dmat->dt_alignment < dmat->dt_maxsize)
+ dmat->dt_alignment <= dmat->dt_maxsize)
*vaddr = malloc(dmat->dt_maxsize, M_DEVBUF, mflags);
else {
/*
diff --git a/sys/x86/x86/busdma_bounce.c b/sys/x86/x86/busdma_bounce.c
index 38c9f1e..bb63397 100644
--- a/sys/x86/x86/busdma_bounce.c
+++ b/sys/x86/x86/busdma_bounce.c
@@ -402,14 +402,14 @@ bounce_bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
/*
* XXX:
- * (dmat->alignment < dmat->maxsize) is just a quick hack; the exact
+ * (dmat->alignment <= dmat->maxsize) is just a quick hack; the exact
* alignment guarantees of malloc need to be nailed down, and the
* code below should be rewritten to take that into account.
*
* In the meantime, we'll warn the user if malloc gets it wrong.
*/
if ((dmat->common.maxsize <= PAGE_SIZE) &&
- (dmat->common.alignment < dmat->common.maxsize) &&
+ (dmat->common.alignment <= dmat->common.maxsize) &&
dmat->common.lowaddr >= ptoa((vm_paddr_t)Maxmem) &&
attr == VM_MEMATTR_DEFAULT) {
*vaddr = malloc(dmat->common.maxsize, M_DEVBUF, mflags);
OpenPOWER on IntegriCloud