diff options
author | Christoph Hellwig <hch@lst.de> | 2017-12-23 20:56:02 +0100 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2018-01-15 09:35:48 +0100 |
commit | a25381aa3ae60a2e028c95f1318649b13cbbce30 (patch) | |
tree | 33eb75af3f080f6f1e6a8210c59731cd11243273 /lib/swiotlb.c | |
parent | aaf796dc6e84e809e4c791b6517326b26312c972 (diff) |
swiotlb: refactor coherent buffer freeing
Factor out a new swiotlb_free_buffer helper that checks if an address
is allocated from the swiotlb bounce buffer, and if yes frees it.
This allows to simplify the swiotlb_free implemenation that uses
dma_direct_free to free the non-bounce buffer allocations.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Christian König <christian.koenig@amd.com>
Diffstat (limited to 'lib/swiotlb.c')
-rw-r--r-- | lib/swiotlb.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 539fd1099ba9..1a147f1354a1 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -780,22 +780,31 @@ err_warn: } EXPORT_SYMBOL(swiotlb_alloc_coherent); +static bool swiotlb_free_buffer(struct device *dev, size_t size, + dma_addr_t dma_addr) +{ + phys_addr_t phys_addr = dma_to_phys(dev, dma_addr); + + WARN_ON_ONCE(irqs_disabled()); + + if (!is_swiotlb_buffer(phys_addr)) + return false; + + /* + * DMA_TO_DEVICE to avoid memcpy in swiotlb_tbl_unmap_single. + * DMA_ATTR_SKIP_CPU_SYNC is optional. + */ + swiotlb_tbl_unmap_single(dev, phys_addr, size, DMA_TO_DEVICE, + DMA_ATTR_SKIP_CPU_SYNC); + return true; +} + void swiotlb_free_coherent(struct device *hwdev, size_t size, void *vaddr, dma_addr_t dev_addr) { - phys_addr_t paddr = dma_to_phys(hwdev, dev_addr); - - WARN_ON(irqs_disabled()); - if (!is_swiotlb_buffer(paddr)) + if (!swiotlb_free_buffer(hwdev, size, dev_addr)) free_pages((unsigned long)vaddr, get_order(size)); - else - /* - * DMA_TO_DEVICE to avoid memcpy in swiotlb_tbl_unmap_single. - * DMA_ATTR_SKIP_CPU_SYNC is optional. - */ - swiotlb_tbl_unmap_single(hwdev, paddr, size, DMA_TO_DEVICE, - DMA_ATTR_SKIP_CPU_SYNC); } EXPORT_SYMBOL(swiotlb_free_coherent); @@ -1110,9 +1119,7 @@ void *swiotlb_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle, void swiotlb_free(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_addr, unsigned long attrs) { - if (is_swiotlb_buffer(dma_to_phys(dev, dma_addr))) - swiotlb_free_coherent(dev, size, vaddr, dma_addr); - else + if (!swiotlb_free_buffer(dev, size, dma_addr)) dma_direct_free(dev, size, vaddr, dma_addr, attrs); } |