[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v5 13/16] swiotlb: Add restricted DMA alloc/free support.



Add the functions, swiotlb_{alloc,free} to support the memory allocation
from restricted DMA pool.

Signed-off-by: Claire Chang <tientzu@xxxxxxxxxxxx>
---
 include/linux/swiotlb.h |  4 ++++
 kernel/dma/swiotlb.c    | 35 +++++++++++++++++++++++++++++++++--
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 0c5a18d9cf89..e8cf49bd90c5 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -134,6 +134,10 @@ unsigned int swiotlb_max_segment(void);
 size_t swiotlb_max_mapping_size(struct device *dev);
 bool is_swiotlb_active(struct device *dev);
 void __init swiotlb_adjust_size(unsigned long size);
+#ifdef CONFIG_DMA_RESTRICTED_POOL
+struct page *swiotlb_alloc(struct device *dev, size_t size);
+bool swiotlb_free(struct device *dev, struct page *page, size_t size);
+#endif /* CONFIG_DMA_RESTRICTED_POOL */
 #else
 #define swiotlb_force SWIOTLB_NO_FORCE
 static inline bool is_swiotlb_buffer(struct device *dev, phys_addr_t paddr)
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index af0feb8eaead..274272c79080 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -454,8 +454,9 @@ static int find_slots(struct device *dev, phys_addr_t 
orig_addr,
 
        index = wrap = wrap_index(mem, ALIGN(mem->index, stride));
        do {
-               if ((slot_addr(tbl_dma_addr, index) & iotlb_align_mask) !=
-                   (orig_addr & iotlb_align_mask)) {
+               if (orig_addr &&
+                   (slot_addr(tbl_dma_addr, index) & iotlb_align_mask) !=
+                           (orig_addr & iotlb_align_mask)) {
                        index = wrap_index(mem, index + 1);
                        continue;
                }
@@ -695,6 +696,36 @@ late_initcall(swiotlb_create_default_debugfs);
 #endif
 
 #ifdef CONFIG_DMA_RESTRICTED_POOL
+struct page *swiotlb_alloc(struct device *dev, size_t size)
+{
+       struct io_tlb_mem *mem = dev->dma_io_tlb_mem;
+       phys_addr_t tlb_addr;
+       int index;
+
+       if (!mem)
+               return NULL;
+
+       index = find_slots(dev, 0, size);
+       if (index == -1)
+               return NULL;
+
+       tlb_addr = slot_addr(mem->start, index);
+
+       return pfn_to_page(PFN_DOWN(tlb_addr));
+}
+
+bool swiotlb_free(struct device *dev, struct page *page, size_t size)
+{
+       phys_addr_t tlb_addr = page_to_phys(page);
+
+       if (!is_swiotlb_buffer(dev, tlb_addr))
+               return false;
+
+       release_slots(dev, tlb_addr);
+
+       return true;
+}
+
 static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
                                    struct device *dev)
 {
-- 
2.31.1.368.gbe11c130af-goog




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.