forked from mirrors/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>
This commit is contained in:
		
							parent
							
								
									646010009d
								
							
						
					
					
						commit
						08b0b0059b
					
				
					 12 changed files with 39 additions and 4 deletions
				
			
		|  | @ -326,6 +326,12 @@ maps this page at its virtual address. | |||
| 			dirty.  Again, see sparc64 for examples of how | ||||
| 			to deal with this. | ||||
| 
 | ||||
|   ``void flush_dcache_folio(struct folio *folio)`` | ||||
| 	This function is called under the same circumstances as | ||||
| 	flush_dcache_page().  It allows the architecture to | ||||
| 	optimise for flushing the entire folio of pages instead | ||||
| 	of flushing one page at a time. | ||||
| 
 | ||||
|   ``void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | ||||
|   unsigned long user_vaddr, void *dst, void *src, int len)`` | ||||
|   ``void copy_from_user_page(struct vm_area_struct *vma, struct page *page, | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ void __flush_dcache_page(phys_addr_t paddr, unsigned long vaddr); | |||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | ||||
| 
 | ||||
| void flush_dcache_page(struct page *page); | ||||
| void flush_dcache_folio(struct folio *folio); | ||||
| 
 | ||||
| void dma_cache_wback_inv(phys_addr_t start, unsigned long sz); | ||||
| void dma_cache_inv(phys_addr_t start, unsigned long sz); | ||||
|  |  | |||
|  | @ -290,6 +290,7 @@ extern void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr | |||
|  */ | ||||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | ||||
| extern void flush_dcache_page(struct page *); | ||||
| void flush_dcache_folio(struct folio *folio); | ||||
| 
 | ||||
| #define ARCH_IMPLEMENTS_FLUSH_KERNEL_VMAP_RANGE 1 | ||||
| static inline void flush_kernel_vmap_range(void *addr, int size) | ||||
|  |  | |||
|  | @ -250,6 +250,7 @@ static inline void __flush_page_to_ram(void *vaddr) | |||
| 
 | ||||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | ||||
| #define flush_dcache_page(page)		__flush_page_to_ram(page_address(page)) | ||||
| void flush_dcache_folio(struct folio *folio); | ||||
| #define flush_dcache_mmap_lock(mapping)		do { } while (0) | ||||
| #define flush_dcache_mmap_unlock(mapping)	do { } while (0) | ||||
| #define flush_icache_page(vma, page)	__flush_page_to_ram(page_address(page)) | ||||
|  |  | |||
|  | @ -61,6 +61,8 @@ static inline void flush_dcache_page(struct page *page) | |||
| 		SetPageDcacheDirty(page); | ||||
| } | ||||
| 
 | ||||
| void flush_dcache_folio(struct folio *folio); | ||||
| 
 | ||||
| #define flush_dcache_mmap_lock(mapping)		do { } while (0) | ||||
| #define flush_dcache_mmap_unlock(mapping)	do { } while (0) | ||||
| 
 | ||||
|  |  | |||
|  | @ -27,6 +27,7 @@ void flush_cache_vunmap(unsigned long start, unsigned long end); | |||
| 
 | ||||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | ||||
| void flush_dcache_page(struct page *page); | ||||
| void flush_dcache_folio(struct folio *folio); | ||||
| void copy_to_user_page(struct vm_area_struct *vma, struct page *page, | ||||
| 		       unsigned long vaddr, void *dst, void *src, int len); | ||||
| void copy_from_user_page(struct vm_area_struct *vma, struct page *page, | ||||
|  |  | |||
|  | @ -28,7 +28,8 @@ extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, | |||
| extern void flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, | ||||
| 	unsigned long pfn); | ||||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | ||||
| extern void flush_dcache_page(struct page *page); | ||||
| void flush_dcache_page(struct page *page); | ||||
| void flush_dcache_folio(struct folio *folio); | ||||
| 
 | ||||
| extern void flush_icache_range(unsigned long start, unsigned long end); | ||||
| extern void flush_icache_page(struct vm_area_struct *vma, struct page *page); | ||||
|  |  | |||
|  | @ -49,7 +49,8 @@ void invalidate_kernel_vmap_range(void *vaddr, int size); | |||
| #define flush_cache_vunmap(start, end)		flush_cache_all() | ||||
| 
 | ||||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | ||||
| extern void flush_dcache_page(struct page *page); | ||||
| void flush_dcache_page(struct page *page); | ||||
| void flush_dcache_folio(struct folio *folio); | ||||
| 
 | ||||
| #define flush_dcache_mmap_lock(mapping)		xa_lock_irq(&mapping->i_pages) | ||||
| #define flush_dcache_mmap_unlock(mapping)	xa_unlock_irq(&mapping->i_pages) | ||||
|  |  | |||
|  | @ -42,7 +42,8 @@ extern void flush_cache_page(struct vm_area_struct *vma, | |||
| extern void flush_cache_range(struct vm_area_struct *vma, | ||||
| 				 unsigned long start, unsigned long end); | ||||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | ||||
| extern void flush_dcache_page(struct page *page); | ||||
| void flush_dcache_page(struct page *page); | ||||
| void flush_dcache_folio(struct folio *folio); | ||||
| extern void flush_icache_range(unsigned long start, unsigned long end); | ||||
| #define flush_icache_user_range flush_icache_range | ||||
| extern void flush_icache_page(struct vm_area_struct *vma, | ||||
|  |  | |||
|  | @ -120,7 +120,8 @@ void flush_cache_page(struct vm_area_struct*, | |||
| #define flush_cache_vunmap(start,end)	flush_cache_all() | ||||
| 
 | ||||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 | ||||
| extern void flush_dcache_page(struct page*); | ||||
| void flush_dcache_page(struct page *); | ||||
| void flush_dcache_folio(struct folio *); | ||||
| 
 | ||||
| void local_flush_cache_range(struct vm_area_struct *vma, | ||||
| 		unsigned long start, unsigned long end); | ||||
|  | @ -137,7 +138,9 @@ void local_flush_cache_page(struct vm_area_struct *vma, | |||
| #define flush_cache_vunmap(start,end)			do { } while (0) | ||||
| 
 | ||||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 | ||||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO | ||||
| #define flush_dcache_page(page)				do { } while (0) | ||||
| static inline void flush_dcache_folio(struct folio *folio) { } | ||||
| 
 | ||||
| #define flush_icache_range local_flush_icache_range | ||||
| #define flush_cache_page(vma, addr, pfn)		do { } while (0) | ||||
|  |  | |||
|  | @ -49,9 +49,15 @@ static inline void flush_cache_page(struct vm_area_struct *vma, | |||
| static inline void flush_dcache_page(struct page *page) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static inline void flush_dcache_folio(struct folio *folio) { } | ||||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0 | ||||
| #define ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO | ||||
| #endif | ||||
| 
 | ||||
| #ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO | ||||
| void flush_dcache_folio(struct folio *folio); | ||||
| #endif | ||||
| 
 | ||||
| #ifndef flush_dcache_mmap_lock | ||||
| static inline void flush_dcache_mmap_lock(struct address_space *mapping) | ||||
|  |  | |||
							
								
								
									
										11
									
								
								mm/util.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								mm/util.c
									
									
									
									
									
								
							|  | @ -1076,3 +1076,14 @@ void page_offline_end(void) | |||
| 	up_write(&page_offline_rwsem); | ||||
| } | ||||
| EXPORT_SYMBOL(page_offline_end); | ||||
| 
 | ||||
| #ifndef ARCH_IMPLEMENTS_FLUSH_DCACHE_FOLIO | ||||
| void flush_dcache_folio(struct folio *folio) | ||||
| { | ||||
| 	long i, nr = folio_nr_pages(folio); | ||||
| 
 | ||||
| 	for (i = 0; i < nr; i++) | ||||
| 		flush_dcache_page(folio_page(folio, i)); | ||||
| } | ||||
| EXPORT_SYMBOL(flush_dcache_folio); | ||||
| #endif | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Matthew Wilcox (Oracle)
						Matthew Wilcox (Oracle)