linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Fix folio conversion in __dma_page_dev_to_cpu()
@ 2023-08-23 19:18 Matthew Wilcox (Oracle)
  2023-08-24 16:39 ` Robin Murphy
  0 siblings, 1 reply; 4+ messages in thread
From: Matthew Wilcox (Oracle) @ 2023-08-23 19:18 UTC (permalink / raw)
  To: Russell King, Andrew Morton
  Cc: Matthew Wilcox (Oracle), Marek Szyprowski, linux-arm-kernel, linux-mm

Russell and Marek pointed out some assumptions I was making about how sg
lists work; eg that they are limited to 2GB and that the initial offset
lies within the first page (or at least within the first folio that a
page belongs to).  While I think those assumptions are true, it's not
too hard to write a version which does not have those assumptions and
also calculates folio_size() only once per loop iteration.

---
 arch/arm/mm/dma-mapping.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 0474840224d9..5409225b4abc 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -695,7 +695,6 @@ static void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
 static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
 	size_t size, enum dma_data_direction dir)
 {
-	struct folio *folio = page_folio(page);
 	phys_addr_t paddr = page_to_phys(page) + off;
 
 	/* FIXME: non-speculating: not required */
@@ -710,18 +709,19 @@ static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
 	 * Mark the D-cache clean for these pages to avoid extra flushing.
 	 */
 	if (dir != DMA_TO_DEVICE && size >= PAGE_SIZE) {
-		ssize_t left = size;
+		struct folio *folio = pfn_folio(paddr / PAGE_SIZE);
 		size_t offset = offset_in_folio(folio, paddr);
 
-		if (offset) {
-			left -= folio_size(folio) - offset;
-			folio = folio_next(folio);
-		}
+		for (;;) {
+			size_t sz = folio_size(folio) - offset;
 
-		while (left >= (ssize_t)folio_size(folio)) {
-			left -= folio_size(folio);
-			set_bit(PG_dcache_clean, &folio->flags);
-			if (!left)
+			if (size < sz)
+				break;
+			if (!offset)
+				set_bit(PG_dcache_clean, &folio->flags);
+			offset = 0;
+			size -= sz;
+			if (!size)
 				break;
 			folio = folio_next(folio);
 		}
-- 
2.40.1



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-08-24 17:15 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-23 19:18 [PATCH] Fix folio conversion in __dma_page_dev_to_cpu() Matthew Wilcox (Oracle)
2023-08-24 16:39 ` Robin Murphy
2023-08-24 16:49   ` Matthew Wilcox
2023-08-24 17:14     ` Robin Murphy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox