Commit f6826a07 authored by Andi Kleen's avatar Andi Kleen Committed by Linus Torvalds

[PATCH] x86_64: Fallback to swiotlb for dma_alloc_coherent

From: Suresh B Siddha

Coresponding change to IA64 code is in, so this can be merged too.

- fallback to swiotlb for consistent DMA mappings
- fix a memory leak in dma_alloc_coherent
Signed-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 6eb10fe9
......@@ -236,11 +236,21 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
mmu = 1;
if (no_iommu || dma_mask < 0xffffffffUL) {
if (high) {
free_pages((unsigned long)memory,
get_order(size));
if (swiotlb) {
return
swiotlb_alloc_coherent(dev, size,
dma_handle,
gfp);
}
if (!(gfp & GFP_DMA)) {
gfp |= GFP_DMA;
goto again;
}
goto free;
return NULL;
}
mmu = 0;
}
......@@ -260,9 +270,7 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
error:
if (panic_on_overflow)
panic("dma_alloc_coherent: IOMMU overflow by %lu bytes\n", size);
free:
free_pages((unsigned long)memory, get_order(size));
/* XXX Could use the swiotlb pool here too */
return NULL;
}
......@@ -273,6 +281,11 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
void dma_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t bus)
{
if (swiotlb) {
swiotlb_free_coherent(dev, size, vaddr, bus);
return;
}
dma_unmap_single(dev, bus, size, 0);
free_pages((unsigned long)vaddr, get_order(size));
}
......
......@@ -26,6 +26,10 @@ extern int swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg,
extern void swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg,
int nents, int direction);
extern int swiotlb_dma_mapping_error(dma_addr_t dma_addr);
extern void *swiotlb_alloc_coherent (struct device *hwdev, size_t size,
dma_addr_t *dma_handle, int flags);
extern void swiotlb_free_coherent (struct device *hwdev, size_t size,
void *vaddr, dma_addr_t dma_handle);
#ifdef CONFIG_SWIOTLB
extern int swiotlb;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment