swiotlb: refactor coherent buffer freeing
authorChristoph Hellwig <hch@lst.de>
Sat, 23 Dec 2017 19:56:02 +0000 (20:56 +0100)
committerChristoph Hellwig <hch@lst.de>
Mon, 15 Jan 2018 08:35:48 +0000 (09:35 +0100)
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>
lib/swiotlb.c

index 539fd1099ba9f93bfa0d2c40f548ab66ad34ffc5..1a147f1354a18c68bbc2673d1ef87c7209a95980 100644 (file)
@@ -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);
 }