Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ARM: dma-mapping: Reduce struct page exposure in arch_sync_dma*()

As a preparation to changing from .map_page to use .map_phys DMA
callbacks, convert arch_sync_dma*() functions to use physical addresses
instead of struct page.

Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Link: https://lore.kernel.org/r/20251015-remove-map-page-v5-3-3bbfe3a25cdf@kernel.org

authored by

Leon Romanovsky and committed by
Marek Szyprowski
52c9aa1a 45fa6d19

+31 -51
+31 -51
arch/arm/mm/dma-mapping.c
··· 624 624 kfree(buf); 625 625 } 626 626 627 - static void dma_cache_maint_page(struct page *page, unsigned long offset, 628 - size_t size, enum dma_data_direction dir, 627 + static void dma_cache_maint_page(phys_addr_t phys, size_t size, 628 + enum dma_data_direction dir, 629 629 void (*op)(const void *, size_t, int)) 630 630 { 631 - unsigned long pfn; 631 + unsigned long offset = offset_in_page(phys); 632 + unsigned long pfn = __phys_to_pfn(phys); 632 633 size_t left = size; 633 - 634 - pfn = page_to_pfn(page) + offset / PAGE_SIZE; 635 - offset %= PAGE_SIZE; 636 634 637 635 /* 638 636 * A single sg entry may refer to multiple physically contiguous ··· 642 644 size_t len = left; 643 645 void *vaddr; 644 646 645 - page = pfn_to_page(pfn); 646 - 647 - if (PageHighMem(page)) { 647 + phys = __pfn_to_phys(pfn); 648 + if (PhysHighMem(phys)) { 648 649 if (len + offset > PAGE_SIZE) 649 650 len = PAGE_SIZE - offset; 650 651 651 652 if (cache_is_vipt_nonaliasing()) { 652 - vaddr = kmap_atomic(page); 653 + vaddr = kmap_atomic_pfn(pfn); 653 654 op(vaddr + offset, len, dir); 654 655 kunmap_atomic(vaddr); 655 656 } else { 657 + struct page *page = phys_to_page(phys); 658 + 656 659 vaddr = kmap_high_get(page); 657 660 if (vaddr) { 658 661 op(vaddr + offset, len, dir); ··· 661 662 } 662 663 } 663 664 } else { 664 - vaddr = page_address(page) + offset; 665 + phys += offset; 666 + vaddr = phys_to_virt(phys); 665 667 op(vaddr, len, dir); 666 668 } 667 669 offset = 0; ··· 676 676 * Note: Drivers should NOT use this function directly. 677 677 * Use the driver DMA support - see dma-mapping.h (dma_sync_*) 678 678 */ 679 - static void __dma_page_cpu_to_dev(struct page *page, unsigned long off, 680 - size_t size, enum dma_data_direction dir) 679 + void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, 680 + enum dma_data_direction dir) 681 681 { 682 - phys_addr_t paddr; 682 + dma_cache_maint_page(paddr, size, dir, dmac_map_area); 683 683 684 - dma_cache_maint_page(page, off, size, dir, dmac_map_area); 685 - 686 - paddr = page_to_phys(page) + off; 687 684 if (dir == DMA_FROM_DEVICE) { 688 685 outer_inv_range(paddr, paddr + size); 689 686 } else { ··· 689 692 /* FIXME: non-speculating: flush on bidirectional mappings? */ 690 693 } 691 694 692 - static void __dma_page_dev_to_cpu(struct page *page, unsigned long off, 693 - size_t size, enum dma_data_direction dir) 695 + void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, 696 + enum dma_data_direction dir) 694 697 { 695 - phys_addr_t paddr = page_to_phys(page) + off; 696 - 697 698 /* FIXME: non-speculating: not required */ 698 699 /* in any case, don't bother invalidating if DMA to device */ 699 700 if (dir != DMA_TO_DEVICE) { 700 701 outer_inv_range(paddr, paddr + size); 701 702 702 - dma_cache_maint_page(page, off, size, dir, dmac_unmap_area); 703 + dma_cache_maint_page(paddr, size, dir, dmac_unmap_area); 703 704 } 704 705 705 706 /* ··· 1200 1205 unsigned int len = PAGE_ALIGN(s->offset + s->length); 1201 1206 1202 1207 if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) 1203 - __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir); 1208 + arch_sync_dma_for_device(sg_phys(s), s->length, dir); 1204 1209 1205 1210 prot = __dma_info_to_prot(dir, attrs); 1206 1211 ··· 1302 1307 __iommu_remove_mapping(dev, sg_dma_address(s), 1303 1308 sg_dma_len(s)); 1304 1309 if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) 1305 - __dma_page_dev_to_cpu(sg_page(s), s->offset, 1306 - s->length, dir); 1310 + arch_sync_dma_for_cpu(sg_phys(s), s->length, dir); 1307 1311 } 1308 1312 } 1309 1313 ··· 1324 1330 return; 1325 1331 1326 1332 for_each_sg(sg, s, nents, i) 1327 - __dma_page_dev_to_cpu(sg_page(s), s->offset, s->length, dir); 1333 + arch_sync_dma_for_cpu(sg_phys(s), s->length, dir); 1328 1334 1329 1335 } 1330 1336 ··· 1346 1352 return; 1347 1353 1348 1354 for_each_sg(sg, s, nents, i) 1349 - __dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir); 1355 + arch_sync_dma_for_device(sg_phys(s), s->length, dir); 1350 1356 } 1351 1357 1352 1358 /** ··· 1368 1374 int ret, prot, len = PAGE_ALIGN(size + offset); 1369 1375 1370 1376 if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) 1371 - __dma_page_cpu_to_dev(page, offset, size, dir); 1377 + arch_sync_dma_for_device(page_to_phys(page), offset, size, dir); 1372 1378 1373 1379 dma_addr = __alloc_iova(mapping, len); 1374 1380 if (dma_addr == DMA_MAPPING_ERROR) ··· 1401 1407 { 1402 1408 struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); 1403 1409 dma_addr_t iova = handle & PAGE_MASK; 1404 - struct page *page; 1405 1410 int offset = handle & ~PAGE_MASK; 1406 1411 int len = PAGE_ALIGN(size + offset); 1407 1412 ··· 1408 1415 return; 1409 1416 1410 1417 if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) { 1411 - page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova)); 1412 - __dma_page_dev_to_cpu(page, offset, size, dir); 1418 + phys_addr_t phys = iommu_iova_to_phys(mapping->domain, iova); 1419 + 1420 + arch_sync_dma_for_cpu(phys + offset, size, dir); 1413 1421 } 1414 1422 1415 1423 iommu_unmap(mapping->domain, iova, len); ··· 1479 1485 { 1480 1486 struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); 1481 1487 dma_addr_t iova = handle & PAGE_MASK; 1482 - struct page *page; 1483 1488 unsigned int offset = handle & ~PAGE_MASK; 1489 + phys_addr_t phys; 1484 1490 1485 1491 if (dev->dma_coherent || !iova) 1486 1492 return; 1487 1493 1488 - page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova)); 1489 - __dma_page_dev_to_cpu(page, offset, size, dir); 1494 + phys = iommu_iova_to_phys(mapping->domain, iova); 1495 + arch_sync_dma_for_cpu(phys + offset, size, dir); 1490 1496 } 1491 1497 1492 1498 static void arm_iommu_sync_single_for_device(struct device *dev, ··· 1494 1500 { 1495 1501 struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); 1496 1502 dma_addr_t iova = handle & PAGE_MASK; 1497 - struct page *page; 1498 1503 unsigned int offset = handle & ~PAGE_MASK; 1504 + phys_addr_t phys; 1499 1505 1500 1506 if (dev->dma_coherent || !iova) 1501 1507 return; 1502 1508 1503 - page = phys_to_page(iommu_iova_to_phys(mapping->domain, iova)); 1504 - __dma_page_cpu_to_dev(page, offset, size, dir); 1509 + phys = iommu_iova_to_phys(mapping->domain, iova); 1510 + arch_sync_dma_for_device(phys + offset, size, dir); 1505 1511 } 1506 1512 1507 1513 static const struct dma_map_ops iommu_ops = { ··· 1786 1792 arm_teardown_iommu_dma_ops(dev); 1787 1793 /* Let arch_setup_dma_ops() start again from scratch upon re-probe */ 1788 1794 set_dma_ops(dev, NULL); 1789 - } 1790 - 1791 - void arch_sync_dma_for_device(phys_addr_t paddr, size_t size, 1792 - enum dma_data_direction dir) 1793 - { 1794 - __dma_page_cpu_to_dev(phys_to_page(paddr), paddr & (PAGE_SIZE - 1), 1795 - size, dir); 1796 - } 1797 - 1798 - void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t size, 1799 - enum dma_data_direction dir) 1800 - { 1801 - __dma_page_dev_to_cpu(phys_to_page(paddr), paddr & (PAGE_SIZE - 1), 1802 - size, dir); 1803 1795 } 1804 1796 1805 1797 void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_handle,