summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorsilby <silby@FreeBSD.org>2006-05-28 18:31:32 +0000
committersilby <silby@FreeBSD.org>2006-05-28 18:31:32 +0000
commit0daaa33f18003993aa6051fcc24b2bfff9abd912 (patch)
treec91c5e8aee80a8424cb9aac46d9ec8436b034893 /sys/amd64
parent7f96e8451ab97fb9114eb33c776cdfa1f64bd5fc (diff)
downloadFreeBSD-src-0daaa33f18003993aa6051fcc24b2bfff9abd912.zip
FreeBSD-src-0daaa33f18003993aa6051fcc24b2bfff9abd912.tar.gz
MFi386 rev 1.78:
Add a quick hack to ensure that bus_dmamem_alloc properly aligns small allocations with large alignment requirements. Add a panic to detect cases where we've still failed to properly align.
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/busdma_machdep.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/sys/amd64/amd64/busdma_machdep.c b/sys/amd64/amd64/busdma_machdep.c
index 348ab78..20dae8a 100644
--- a/sys/amd64/amd64/busdma_machdep.c
+++ b/sys/amd64/amd64/busdma_machdep.c
@@ -492,7 +492,16 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
}
}
+ /*
+ * XXX:
+ * (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 panic if malloc gets it wrong.
+ */
if ((dmat->maxsize <= PAGE_SIZE) &&
+ (dmat->alignment < dmat->maxsize) &&
dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem)) {
*vaddr = malloc(dmat->maxsize, M_DEVBUF, mflags);
} else {
@@ -510,6 +519,8 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
__func__, dmat, dmat->flags, ENOMEM);
return (ENOMEM);
+ } else if ((uintptr_t)*vaddr & (dmat->alignment - 1)) {
+ panic("bus_dmamem_alloc failed to align memory properly.");
}
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
__func__, dmat, dmat->flags, ENOMEM);
@@ -529,8 +540,9 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map)
*/
if (map != NULL)
panic("bus_dmamem_free: Invalid map freed\n");
- if ((dmat->maxsize <= PAGE_SIZE)
- && dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem))
+ if ((dmat->maxsize <= PAGE_SIZE) &&
+ (dmat->alignment < dmat->maxsize) &&
+ dmat->lowaddr >= ptoa((vm_paddr_t)Maxmem))
free(vaddr, M_DEVBUF);
else {
contigfree(vaddr, dmat->maxsize, M_DEVBUF);
OpenPOWER on IntegriCloud