Preparation to .map_page and .unmap_page removal
cover Preparation to .map_page and .unmap_page removal
Changelog:
v1:
* 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 | 24 ++++++++++++++++++++---- kernel/dma/ops_helpers.c | 14 +++++++++++--- 4 files changed, 43 insertions(+), 14 deletions(-)
Signature · 1 line
2.50.1
PATCH 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 | 24 ++++++++++++++++++++---- kernel/dma/ops_helpers.c | 14 +++++++++++--- 3 files changed, 37 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 +20 -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,11 @@ 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); }kmsan_handle_dma (phys, size, dir);
@@ -213,8 +221,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 +11 -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,10 +72,14 @@ 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 );if (*dma_handle ==DMA_MAPPING_ERROR ) {
@@ -94,6 +99,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
kernel test robot
build botRe: [PATCH v1 1/2] dma-mapping: prepare dma_map_ops to conversion to physical address
kernel test robot noticed the following build warnings:
Hi Leon,
kernel test robot noticed the following build warnings:
[auto build test WARNING on next-20250718]
[cannot apply to linus/master v6.16-rc6 v6.16-rc5 v6.16-rc4 v6.16-rc6] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Leon-Romanovsky/dma-mapping-prepare-dma_map_ops-to-conversion-to-physical-address/20250720-173726 base: next-20250718 patch link: https://lore.kernel.org/r/184fc9bda626efc62c5022ace01a20b80d1dc93b.1753003879.git.leon%40kernel.org patch subject: [PATCH v1 1/2] dma-mapping: prepare dma_map_ops to conversion to physical address config: s390-randconfig-001-20250720 (https://download.01.org/0day-ci/archive/20250720/[email protected]/config) compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project 16534d19bf50bde879a83f0ae62875e2c5120e64) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250720/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
>> kernel/dma/mapping.c:192:12: warning: variable 'addr' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
192 | else if (ops->map_page)
| ^~~~~~~~~~~~~
kernel/dma/mapping.c:198:32: note: uninitialized use occurs here
198 | trace_dma_map_phys(dev, phys, addr, size, dir, attrs);
| ^~~~
kernel/dma/mapping.c:192:8: note: remove the 'if' if its condition is always true
192 | else if (ops->map_page)
| ^~~~~~~~~~~~~~~~~~
193 | addr = ops->map_page(dev, page, offset, size, dir,
kernel/dma/mapping.c:159:17: note: initialize the variable 'addr' to silence this warning
159 | dma_addr_t addr;
| ^
| = 01 warning generated.
vim +192 kernel/dma/mapping.c
154
155 dma_addr_t dma_map_phys(struct device *dev, phys_addr_t phys, size_t size,
156 enum dma_data_direction dir, unsigned long attrs)
157 {
158 const struct dma_map_ops *ops = get_dma_ops(dev);
159 dma_addr_t addr;
160
161 BUG_ON(!valid_dma_direction(dir));
162
163 if (WARN_ON_ONCE(!dev->dma_mask))
164 return DMA_MAPPING_ERROR;
165
166 if (dma_map_direct(dev, ops) ||
167 arch_dma_map_phys_direct(dev, phys + size))
168 addr = dma_direct_map_phys(dev, phys, size, dir, attrs);
169 else if (use_dma_iommu(dev))
170 addr = iommu_dma_map_phys(dev, phys, size, dir, attrs);
171 else {
172 struct page *page = phys_to_page(phys);
173 size_t offset = offset_in_page(phys);
174 bool is_pfn_valid = true;
175
176 if (IS_ENABLED(CONFIG_DMA_API_DEBUG)) {
177 is_pfn_valid = pfn_valid(PHYS_PFN(phys));
178
179 /* We shouldn't have both functions */
180 WARN_ON_ONCE(ops->map_page && ops->map_phys);
181 }
182
183 if (unlikely(!is_pfn_valid))
184 return DMA_MAPPING_ERROR;
185
186 /*
187 * All platforms which implement .map_page() don't support
188 * non-struct page backed addresses.
189 */
190 if (ops->map_phys)
191 addr = ops->map_phys(dev, phys, size, dir, attrs);
> 192 else if (ops->map_page)
193 addr = ops->map_page(dev, page, offset, size, dir,
194 attrs);
195 }
196
197 kmsan_handle_dma(phys, size, dir);
198 trace_dma_map_phys(dev, phys, addr, size, dir, attrs);
199 debug_dma_map_phys(dev, phys, size, dir, addr, attrs);
200
201 return addr;
202 }
203 EXPORT_SYMBOL_GPL(dma_map_phys);
204
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
Re: [PATCH v1 1/2] dma-mapping: prepare dma_map_ops to conversion to physical address
Quoted 39 lines · kernel test robot
Hi Leon,
kernel test robot noticed the following build warnings:
[auto build test WARNING on next-20250718]
[cannot apply to linus/master v6.16-rc6 v6.16-rc5 v6.16-rc4 v6.16-rc6] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]url: https://github.com/intel-lab-lkp/linux/commits/Leon-Romanovsky/dma-mapping-prepare-dma_map_ops-to-conversion-to-physical-address/20250720-173726 base: next-20250718 patch link: https://lore.kernel.org/r/184fc9bda626efc62c5022ace01a20b80d1dc93b.1753003879.git.leon%40kernel.org patch subject: [PATCH v1 1/2] dma-mapping: prepare dma_map_ops to conversion to physical address config: s390-randconfig-001-20250720 (https://download.01.org/0day-ci/archive/20250720/[email protected]/config) compiler: clang version 21.0.0git (https://github.com/llvm/llvm-project 16534d19bf50bde879a83f0ae62875e2c5120e64) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250720/[email protected]/reproduce)If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/All warnings (new ones prefixed by >>):
Quoted 1 line
Quoted 1 line
kernel/dma/mapping.c:192:12: warning: variable 'addr' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]192 | else if (ops->map_page) | ^~~~~~~~~~~~~ kernel/dma/mapping.c:198:32: note: uninitialized use occurs here 198 | trace_dma_map_phys(dev, phys, addr, size, dir, attrs); | ^~~~ kernel/dma/mapping.c:192:8: note: remove the 'if' if its condition is always true 192 | else if (ops->map_page) | ^~~~~~~~~~~~~~~~~~ 193 | addr = ops->map_page(dev, page, offset, size, dir, kernel/dma/mapping.c:159:17: note: initialize the variable 'addr' to silence this warning 159 | dma_addr_t addr; | ^ | = 0
Quoted 1 line
1 warning generated.
Strange, I didn't get any warning about it for v1.
Thanks
Quoted 59 lines
vim +192
kernel/dma/mapping.c154 155 dma_addr_t dma_map_phys(struct device *dev, phys_addr_t phys, size_t size, 156 enum dma_data_direction dir, unsigned long attrs) 157 { 158 const struct dma_map_ops *ops = get_dma_ops(dev); 159 dma_addr_t addr; 160 161 BUG_ON(!valid_dma_direction(dir)); 162 163 if (WARN_ON_ONCE(!dev->dma_mask)) 164 return DMA_MAPPING_ERROR; 165 166 if (dma_map_direct(dev, ops) || 167 arch_dma_map_phys_direct(dev, phys + size)) 168 addr = dma_direct_map_phys(dev, phys, size, dir, attrs); 169 else if (use_dma_iommu(dev)) 170 addr = iommu_dma_map_phys(dev, phys, size, dir, attrs); 171 else { 172 struct page *page = phys_to_page(phys); 173 size_t offset = offset_in_page(phys); 174 bool is_pfn_valid = true; 175 176 if (IS_ENABLED(CONFIG_DMA_API_DEBUG)) { 177 is_pfn_valid = pfn_valid(PHYS_PFN(phys)); 178 179 /* We shouldn't have both functions */ 180 WARN_ON_ONCE(ops->map_page && ops->map_phys); 181 } 182 183 if (unlikely(!is_pfn_valid)) 184 return DMA_MAPPING_ERROR; 185 186 /* 187 * All platforms which implement .map_page() don't support 188 * non-struct page backed addresses. 189 */ 190 if (ops->map_phys) 191 addr = ops->map_phys(dev, phys, size, dir, attrs);Quoted 1 line
192 else if (
ops->map_page)193 addr = ops->map_page(dev, page, offset, size, dir,
194 attrs); 195 } 196 197 kmsan_handle_dma(phys, size, dir); 198 trace_dma_map_phys(dev, phys, addr, size, dir, attrs); 199 debug_dma_map_phys(dev, phys, size, dir, addr, attrs); 200 201 return addr; 202 } 203 EXPORT_SYMBOL_GPL(dma_map_phys); 204Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
PATCH 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