Preparation to .map_page and .unmap_page removal
v2 cover Preparation to .map_page and .unmap_page removal
Changelog:
v2:
* Added default "else" section without map_phys and map_page callbacks (impossible).
v1: https://lore.kernel.org/all/[email protected]
* Changed "else if" instead of "if".
v0: https://lore.kernel.org/all/[email protected]
---------------------------------------------------------------------
This is followup to "dma-mapping: migrate to physical address-based API" series https://lore.kernel.org/all/[email protected]/
These preparation changes are limited to DMA subsystem to avoid possible complications with submission to multiple trees.
Thanks
Leon Romanovsky (2):
dma-mapping: prepare dma_map_ops to conversion to physical address
dma-mapping: convert dummy ops to physical address mapping
include/linux/dma-map-ops.h | 6 ++++++ kernel/dma/dummy.c | 13 ++++++------- kernel/dma/mapping.c | 26 ++++++++++++++++++++++---- kernel/dma/ops_helpers.c | 17 ++++++++++++++--- 4 files changed, 48 insertions(+), 14 deletions(-)
Signature · 1 line
2.50.1
PATCH v2 1/2 dma-mapping: prepare dma_map_ops to conversion to physical address
From: Leon Romanovsky <[email protected]>
Add new .map_phys() and .unmap_phys() callbacks to dma_map_ops as a preparation to replace .map_page() and .unmap_page() respectively.
--- include/linux/dma-map-ops.h | 6 ++++++ kernel/dma/mapping.c | 26 ++++++++++++++++++++++---- kernel/dma/ops_helpers.c | 17 ++++++++++++++--- 3 files changed, 42 insertions(+), 7 deletions(-)
include/linux/dma-map-ops.h +6 -0
@@ -37,6 +37,12 @@ struct dma_map_ops {void (*unmap_page)(struct device *dev,dma_addr_t dma_handle,size_t size,enum dma_data_direction dir,unsigned long attrs); +dma_addr_t (*map_phys)(struct device *dev,phys_addr_t phys, +size_t size,enum dma_data_direction dir, +unsigned long attrs); +void (*unmap_phys)(struct device *dev,dma_addr_t dma_handle, +size_t size,enum dma_data_direction dir, +unsigned long attrs);/* * map_sg should return a negative error code on error. See * dma_map_sgtable() for a list of appropriate error codes
kernel/dma/mapping.c +22 -4
@@ -173,9 +173,13 @@ dma_addr_t dma_map_phys(struct device *dev, phys_addr_t phys, size_t size,size_t offset =offset_in_page (phys);bool is_pfn_valid = true; -if (IS_ENABLED (CONFIG_DMA_API_DEBUG )) +if (IS_ENABLED (CONFIG_DMA_API_DEBUG )) { is_pfn_valid =pfn_valid (PHYS_PFN (phys)); +/* We shouldn't have both functions */ +WARN_ON_ONCE (ops->map_page && ops->map_phys); + } +if (unlikely (!is_pfn_valid))return DMA_MAPPING_ERROR ;
@@ -183,7 +187,13 @@ dma_addr_t dma_map_phys(struct device *dev, phys_addr_t phys, size_t size,* All platforms which implement .map_page() don't support * non-struct page backed addresses. */ - addr = ops->map_page (dev, page, offset, size, dir, attrs); +if (ops->map_phys) + addr = ops->map_phys (dev, phys, size, dir, attrs); +else if (ops->map_page) + addr = ops->map_page (dev, page, offset, size, dir, + attrs); +else + addr =DMA_MAPPING_ERROR ; }kmsan_handle_dma (phys, size, dir);
@@ -213,8 +223,16 @@ void dma_unmap_phys(struct device *dev, dma_addr_t addr, size_t size,dma_direct_unmap_phys (dev, addr, size, dir, attrs); else if (use_dma_iommu(dev)) iommu_dma_unmap_phys(dev, addr, size, dir, attrs); - else - ops->unmap_page(dev, addr, size, dir, attrs); + else { +if (IS_ENABLED (CONFIG_DMA_API_DEBUG )) +/* We shouldn't have both functions */ +WARN_ON_ONCE (ops->unmap_page && ops->unmap_phys); + +if (ops->unmap_phys) + ops->unmap_phys (dev, addr, size, dir, attrs); +else if (ops->unmap_page) + ops->unmap_page (dev, addr, size, dir, attrs); + }trace_dma_unmap_phys (dev, addr, size, dir, attrs);debug_dma_unmap_phys (dev, addr, size, dir); }
kernel/dma/ops_helpers.c +14 -3
@@ -64,6 +64,7 @@ struct page *dma_common_alloc_pages(struct device *dev, size_t size, {const struct dma_map_ops *ops =get_dma_ops (dev);struct page *page; +phys_addr_t phys; page =dma_alloc_contiguous (dev, size, gfp);if (!page)
@@ -71,12 +72,19 @@ struct page *dma_common_alloc_pages(struct device *dev, size_t size,if (!page)return NULL ; + phys =page_to_phys (page);if (use_dma_iommu (dev)) - *dma_handle =iommu_dma_map_phys (dev,page_to_phys (page), size, - dir,DMA_ATTR_SKIP_CPU_SYNC ); -else + *dma_handle =iommu_dma_map_phys (dev, phys, size, dir, +DMA_ATTR_SKIP_CPU_SYNC ); +else if (ops->map_phys) + *dma_handle = ops->map_phys (dev, phys, size, dir, +DMA_ATTR_SKIP_CPU_SYNC ); +else if (ops->map_page) *dma_handle = ops->map_page (dev, page,0 , size, dir,DMA_ATTR_SKIP_CPU_SYNC ); +else + *dma_handle =DMA_MAPPING_ERROR ; +if (*dma_handle ==DMA_MAPPING_ERROR ) {dma_free_contiguous (dev, page, size);return NULL ;
@@ -94,6 +102,9 @@ void dma_common_free_pages(struct device *dev, size_t size, struct page *page,if (use_dma_iommu (dev))iommu_dma_unmap_phys (dev, dma_handle, size, dir,DMA_ATTR_SKIP_CPU_SYNC ); +else if (ops->unmap_phys) + ops->unmap_phys (dev, dma_handle, size, dir, +DMA_ATTR_SKIP_CPU_SYNC );else if (ops->unmap_page) ops->unmap_page (dev, dma_handle, size, dir,DMA_ATTR_SKIP_CPU_SYNC );
Signature · 1 line
2.50.1
PATCH v2 2/2 dma-mapping: convert dummy ops to physical address mapping
In reply to Leon RomanovskyFrom: Leon Romanovsky <[email protected]>
Change dma_dummy_map_page and dma_dummy_unmap_page routines to accept physical address and rename them.
--- kernel/dma/dummy.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
kernel/dma/dummy.c +6 -7
@@ -11,17 +11,16 @@ static int dma_dummy_mmap(struct device *dev, struct vm_area_struct *vma,return -ENXIO ; } -static dma_addr_t dma_dummy_map_page (struct device *dev,struct page *page, -unsigned long offset,size_t size,enum dma_data_direction dir, -unsigned long attrs) +static dma_addr_t dma_dummy_map_phys (struct device *dev,phys_addr_t phys, +size_t size,enum dma_data_direction dir,unsigned long attrs) {return DMA_MAPPING_ERROR ; } -static void dma_dummy_unmap_page (struct device *dev,dma_addr_t dma_handle, +static void dma_dummy_unmap_phys (struct device *dev,dma_addr_t dma_handle,size_t size,enum dma_data_direction dir,unsigned long attrs) {/* -* Dummy ops doesn't support map_page, so unmap_page should never be +* Dummy ops doesn't support map_phys, so unmap_phys should never be * called. */ WARN_ON_ONCE (true);
@@ -51,8 +50,8 @@ static int dma_dummy_supported(struct device *hwdev, u64 mask)const struct dma_map_ops dma_dummy_ops = { .mmap = dma_dummy_mmap, - .map_page = dma_dummy_map_page, - .unmap_page = dma_dummy_unmap_page, + .map_phys = dma_dummy_map_phys, + .unmap_phys = dma_dummy_unmap_phys, .map_sg = dma_dummy_map_sg, .unmap_sg = dma_dummy_unmap_sg, .dma_supported = dma_dummy_supported,
Signature · 1 line
2.50.1