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

mm: Add flush_dcache_folio()

This is a default implementation which calls flush_dcache_page() on
each page in the folio. If architectures can do better, they should
implement their own version of it.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Acked-by: Vlastimil Babka <vbabka@suse.cz>

+39 -4
+6
Documentation/core-api/cachetlb.rst
··· 326 326 dirty. Again, see sparc64 for examples of how 327 327 to deal with this. 328 328 329 + ``void flush_dcache_folio(struct folio *folio)`` 330 + This function is called under the same circumstances as 331 + flush_dcache_page(). It allows the architecture to 332 + optimise for flushing the entire folio of pages instead 333 + of flushing one page at a time. 334 + 329 335 ``void copy_to_user_page(struct vm_area_struct *vma, struct page *page, 330 336 unsigned long user_vaddr, void *dst, void *src, int len)`` 331 337 ``void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
+1
arch/arc/include/asm/cacheflush.h
··· 36 36 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 37 37 38 38 void flush_dcache_page(struct page *page); 39 + void flush_dcache_folio(struct folio *folio); 39 40 40 41 void dma_cache_wback_inv(phys_addr_t start, unsigned long sz); 41 42 void dma_cache_inv(phys_addr_t start, unsigned long sz);
+1
arch/arm/include/asm/cacheflush.h
··· 290 290 */ 291 291 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 292 292 extern void flush_dcache_page(struct page *); 293 + void flush_dcache_folio(struct folio *folio); 293 294 294 295 #define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1 295 296 static inline void flush_kernel_vmap_range(void *addr, int size)
+1
arch/m68k/include/asm/cacheflush_mm.h
··· 250 250 251 251 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 252 252 #define flush_dcache_page(page) __flush_page_to_ram(page_address(page)) 253 + void flush_dcache_folio(struct folio *folio); 253 254 #define flush_dcache_mmap_lock(mapping) do { } while (0) 254 255 #define flush_dcache_mmap_unlock(mapping) do { } while (0) 255 256 #define flush_icache_page(vma, page) __flush_page_to_ram(page_address(page))
+2
arch/mips/include/asm/cacheflush.h
··· 61 61 SetPageDcacheDirty(page); 62 62 } 63 63 64 + void flush_dcache_folio(struct folio *folio); 65 + 64 66 #define flush_dcache_mmap_lock(mapping) do { } while (0) 65 67 #define flush_dcache_mmap_unlock(mapping) do { } while (0) 66 68
+1
arch/nds32/include/asm/cacheflush.h
··· 27 27 28 28 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 29 29 void flush_dcache_page(struct page *page); 30 + void flush_dcache_folio(struct folio *folio); 30 31 void copy_to_user_page(struct vm_area_struct *vma, struct page *page, 31 32 unsigned long vaddr, void *dst, void *src, int len); 32 33 void copy_from_user_page(struct vm_area_struct *vma, struct page *page,
+2 -1
arch/nios2/include/asm/cacheflush.h
··· 28 28 extern void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, 29 29 unsigned long pfn); 30 30 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 31 - extern void flush_dcache_page(struct page *page); 31 + void flush_dcache_page(struct page *page); 32 + void flush_dcache_folio(struct folio *folio); 32 33 33 34 extern void flush_icache_range(unsigned long start, unsigned long end); 34 35 extern void flush_icache_page(struct vm_area_struct *vma, struct page *page);
+2 -1
arch/parisc/include/asm/cacheflush.h
··· 49 49 #define flush_cache_vunmap(start, end) flush_cache_all() 50 50 51 51 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 52 - extern void flush_dcache_page(struct page *page); 52 + void flush_dcache_page(struct page *page); 53 + void flush_dcache_folio(struct folio *folio); 53 54 54 55 #define flush_dcache_mmap_lock(mapping) xa_lock_irq(&mapping->i_pages) 55 56 #define flush_dcache_mmap_unlock(mapping) xa_unlock_irq(&mapping->i_pages)
+2 -1
arch/sh/include/asm/cacheflush.h
··· 42 42 extern void flush_cache_range(struct vm_area_struct *vma, 43 43 unsigned long start, unsigned long end); 44 44 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 45 - extern void flush_dcache_page(struct page *page); 45 + void flush_dcache_page(struct page *page); 46 + void flush_dcache_folio(struct folio *folio); 46 47 extern void flush_icache_range(unsigned long start, unsigned long end); 47 48 #define flush_icache_user_range flush_icache_range 48 49 extern void flush_icache_page(struct vm_area_struct *vma,
+4 -1
arch/xtensa/include/asm/cacheflush.h
··· 120 120 #define flush_cache_vunmap(start,end) flush_cache_all() 121 121 122 122 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 123 - extern void flush_dcache_page(struct page*); 123 + void flush_dcache_page(struct page *); 124 + void flush_dcache_folio(struct folio *); 124 125 125 126 void local_flush_cache_range(struct vm_area_struct *vma, 126 127 unsigned long start, unsigned long end); ··· 138 137 #define flush_cache_vunmap(start,end) do { } while (0) 139 138 140 139 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 140 + #define ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO 141 141 #define flush_dcache_page(page) do { } while (0) 142 + static inline void flush_dcache_folio(struct folio *folio) { } 142 143 143 144 #define flush_icache_range local_flush_icache_range 144 145 #define flush_cache_page(vma, addr, pfn) do { } while (0)
+6
include/asm-generic/cacheflush.h
··· 49 49 static inline void flush_dcache_page(struct page *page) 50 50 { 51 51 } 52 + 53 + static inline void flush_dcache_folio(struct folio *folio) { } 52 54 #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 55 + #define ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO 53 56 #endif 54 57 58 + #ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO 59 + void flush_dcache_folio(struct folio *folio); 60 + #endif 55 61 56 62 #ifndef flush_dcache_mmap_lock 57 63 static inline void flush_dcache_mmap_lock(struct address_space *mapping)
+11
mm/util.c
··· 1076 1076 up_write(&page_offline_rwsem); 1077 1077 } 1078 1078 EXPORT_SYMBOL(page_offline_end); 1079 + 1080 + #ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO 1081 + void flush_dcache_folio(struct folio *folio) 1082 + { 1083 + long i, nr = folio_nr_pages(folio); 1084 + 1085 + for (i = 0; i < nr; i++) 1086 + flush_dcache_page(folio_page(folio, i)); 1087 + } 1088 + EXPORT_SYMBOL(flush_dcache_folio); 1089 + #endif