Skip to content

Commit

Permalink
mm: Add flush_dcache_folio()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Matthew Wilcox (Oracle) committed Oct 18, 2021
1 parent 6460100 commit 08b0b00
Show file tree
Hide file tree
Showing 12 changed files with 39 additions and 4 deletions.
6 changes: 6 additions & 0 deletions Documentation/core-api/cachetlb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions arch/arc/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions arch/arm/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions arch/m68k/include/asm/cacheflush_mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 2 additions & 0 deletions arch/mips/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
1 change: 1 addition & 0 deletions arch/nds32/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 2 additions & 1 deletion arch/nios2/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion arch/parisc/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion arch/sh/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 4 additions & 1 deletion arch/xtensa/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
Expand Down
6 changes: 6 additions & 0 deletions include/asm-generic/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
11 changes: 11 additions & 0 deletions mm/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 08b0b00

Please sign in to comment.