summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorsilby <silby@FreeBSD.org>2006-05-28 18:30:36 +0000
committersilby <silby@FreeBSD.org>2006-05-28 18:30:36 +0000
commit7f96e8451ab97fb9114eb33c776cdfa1f64bd5fc (patch)
treec14c68b47fc764b517e61a7933941747fc77c163 /sys/i386
parenta13a275341ba58af1d15c4a955742f30713d338b (diff)
downloadFreeBSD-src-7f96e8451ab97fb9114eb33c776cdfa1f64bd5fc.zip
FreeBSD-src-7f96e8451ab97fb9114eb33c776cdfa1f64bd5fc.tar.gz
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/i386')
-rw-r--r--sys/i386/i386/busdma_machdep.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/sys/i386/i386/busdma_machdep.c b/sys/i386/i386/busdma_machdep.c
index 0904bfb..1b2bf39 100644
--- a/sys/i386/i386/busdma_machdep.c
+++ b/sys/i386/i386/busdma_machdep.c
@@ -495,7 +495,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 {
@@ -513,6 +522,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);
@@ -532,8 +543,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