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
|
@ -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 New Issue