riscv/mm: hugepage's PG_dcache_clean flag is only set in head page
authorTong Tiangen <tongtiangen@huawei.com>
Mon, 24 Oct 2022 09:47:24 +0000 (09:47 +0000)
committerPalmer Dabbelt <palmer@rivosinc.com>
Fri, 2 Dec 2022 19:25:49 +0000 (11:25 -0800)
HugeTLB pages are always fully mapped, so only setting head page's
PG_dcache_clean flag is enough.

Signed-off-by: Tong Tiangen <tongtiangen@huawei.com>
Link: https://lore.kernel.org/lkml/20220331065640.5777-2-songmuchun@bytedance.com/
Link: https://lore.kernel.org/r/20221024094725.3054311-2-tongtiangen@huawei.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/include/asm/cacheflush.h
arch/riscv/mm/cacheflush.c

index 8a5c246..c172d05 100644 (file)
@@ -17,6 +17,13 @@ static inline void local_flush_icache_all(void)
 
 static inline void flush_dcache_page(struct page *page)
 {
+       /*
+        * HugeTLB pages are always fully mapped and only head page will be
+        * set PG_dcache_clean (see comments in flush_icache_pte()).
+        */
+       if (PageHuge(page))
+               page = compound_head(page);
+
        if (test_bit(PG_dcache_clean, &page->flags))
                clear_bit(PG_dcache_clean, &page->flags);
 }
index 6cb7d96..062559c 100644 (file)
@@ -82,6 +82,13 @@ void flush_icache_pte(pte_t pte)
 {
        struct page *page = pte_page(pte);
 
+       /*
+        * HugeTLB pages are always fully mapped, so only setting head page's
+        * PG_dcache_clean flag is enough.
+        */
+       if (PageHuge(page))
+               page = compound_head(page);
+
        if (!test_and_set_bit(PG_dcache_clean, &page->flags))
                flush_icache_all();
 }