Turn the panic on not being able to meet alignment constraints

in bus_dmamem_alloc into the more reasonable EINVAL return.

Also, reclaim memory allocated but then not used if we had
an error return.
This commit is contained in:
Matt Jacob 2006-05-31 00:37:56 +00:00
parent 5a4c2d0e02
commit aa57a87a56
2 changed files with 44 additions and 8 deletions

View File

@ -469,7 +469,7 @@ int
bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
bus_dmamap_t *mapp)
{
int mflags;
int mflags, malloc_used, swasnull = 0;
if (flags & BUS_DMA_NOWAIT)
mflags = M_NOWAIT;
@ -490,6 +490,7 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
__func__, dmat, dmat->flags, ENOMEM);
return (ENOMEM);
}
swasnull = 1;
}
/*
@ -498,12 +499,13 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
* 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.
* In the meantime, we'll return an error 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);
malloc_used = 1;
} else {
/*
* XXX Use Contigmalloc until it is merged into this facility
@ -514,13 +516,29 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
*vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags,
0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul,
dmat->boundary);
malloc_used = 0;
}
if (*vaddr == NULL) {
if (swasnull) {
free(dmat->segments, M_DEVBUF);
dmat->segments = NULL;
}
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.");
}
if ((uintptr_t)*vaddr & (dmat->alignment - 1)) {
printf("bus_dmamem_alloc failed to align memory properly.");
if (malloc_used) {
free(*vaddr, M_DEVBUF);
} else {
contigfree(*vaddr, dmat->maxsize, M_DEVBUF);
}
if (swasnull) {
free(dmat->segments, M_DEVBUF);
dmat->segments = NULL;
}
return (EINVAL);
}
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
__func__, dmat, dmat->flags, ENOMEM);

View File

@ -472,7 +472,7 @@ int
bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
bus_dmamap_t *mapp)
{
int mflags;
int mflags, malloc_used, swasnull = 0;
if (flags & BUS_DMA_NOWAIT)
mflags = M_NOWAIT;
@ -493,6 +493,7 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
__func__, dmat, dmat->flags, ENOMEM);
return (ENOMEM);
}
swasnull = 1;
}
/*
@ -501,12 +502,13 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
* 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.
* In the meantime, we'll return an error 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);
malloc_used = 1;
} else {
/*
* XXX Use Contigmalloc until it is merged into this facility
@ -517,13 +519,29 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
*vaddr = contigmalloc(dmat->maxsize, M_DEVBUF, mflags,
0ul, dmat->lowaddr, dmat->alignment? dmat->alignment : 1ul,
dmat->boundary);
malloc_used = 0;
}
if (*vaddr == NULL) {
if (swasnull) {
free(dmat->segments, M_DEVBUF);
dmat->segments = NULL;
}
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.");
}
if ((uintptr_t)*vaddr & (dmat->alignment - 1)) {
printf("bus_dmamem_alloc failed to align memory properly.");
if (malloc_used) {
free(*vaddr, M_DEVBUF);
} else {
contigfree(*vaddr, dmat->maxsize, M_DEVBUF);
}
if (swasnull) {
free(dmat->segments, M_DEVBUF);
dmat->segments = NULL;
}
return (EINVAL);
}
CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x error %d",
__func__, dmat, dmat->flags, ENOMEM);