mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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