diff options
author | silby <silby@FreeBSD.org> | 2006-05-28 18:30:36 +0000 |
---|---|---|
committer | silby <silby@FreeBSD.org> | 2006-05-28 18:30:36 +0000 |
commit | 7f96e8451ab97fb9114eb33c776cdfa1f64bd5fc (patch) | |
tree | c14c68b47fc764b517e61a7933941747fc77c163 /sys/i386 | |
parent | a13a275341ba58af1d15c4a955742f30713d338b (diff) | |
download | FreeBSD-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.c | 16 |
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); |