diff options
author | silby <silby@FreeBSD.org> | 2006-05-28 18:31:32 +0000 |
---|---|---|
committer | silby <silby@FreeBSD.org> | 2006-05-28 18:31:32 +0000 |
commit | 0daaa33f18003993aa6051fcc24b2bfff9abd912 (patch) | |
tree | c91c5e8aee80a8424cb9aac46d9ec8436b034893 | |
parent | 7f96e8451ab97fb9114eb33c776cdfa1f64bd5fc (diff) | |
download | FreeBSD-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.
-rw-r--r-- | sys/amd64/amd64/busdma_machdep.c | 16 |
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); |