From: Zhaoyang Huang <zhaoyang.huang@xxxxxxxxxx> Double times of clear_page observed in an arm SOC(A55) when CONFIG_INIT_ON_ALLOC_DEFAULT_ON is on, which introduced by vma_alloc_zeroed_movable_folio within do_anonymous_pages. Since there is no D-cache operation within v6's clear_user_highpage, I would like to suggest to remove the redundant clear_page. struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma, unsigned long vaddr) { struct folio *folio; //first clear_page invoked by vma_alloc_folio==>alloc_page==>post_alloc_hook folio = vma_alloc_folio(GFP_HIGHUSER_MOVABLE, 0, vma, vaddr, false); if (folio) //second clear_page which is meaningless since it do nothing to D-cache in armv6 clear_user_highpage(&folio->page, vaddr); return folio; } PS: Here are all positions called clear_user_highpage which are paired with alloc_pages. IMO, it is safe to skip the second clear_page under armv6. drivers/media/v4l2-core/videobuf-dma-sg.c:441: clear_user_highpage(page, vmf->address); fs/dax.c:1612: clear_user_highpage(vmf->cow_page, vmf->address); include/linux/highmem.h:231: clear_user_highpage(&folio->page, vaddr); mm/memory.c:5974: clear_user_highpage(p, addr + i * PAGE_SIZE); mm/memory.c:5982: clear_user_highpage(page + idx, addr); mm/shmem.c:2621: clear_user_highpage(&folio->page, dst_addr); mm/khugepaged.c:796: clear_user_highpage(page, _address); Signed-off-by: Zhaoyang Huang <zhaoyang.huang@xxxxxxxxxx> --- arch/arm/mm/copypage-v6.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index a1a71f36d850..6f8bee1b3203 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c @@ -9,6 +9,7 @@ #include <linux/mm.h> #include <linux/highmem.h> #include <linux/pagemap.h> +#include <linux/gfp.h> #include <asm/shmparam.h> #include <asm/tlbflush.h> @@ -45,6 +46,13 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to, */ static void v6_clear_user_highpage_nonaliasing(struct page *page, unsigned long vaddr) { + /* + * This criteria only help bailing out when CONFIG_INIT_ON_ALLOC_DEFAULT_ON + * is on. The page has been memset to zero when it allocated and the + * bellowing clear_page will do it again. + */ + if (want_init_on_alloc(GFP_HIGHUSER_MOVABLE)) + return; void *kaddr = kmap_atomic(page); clear_page(kaddr); kunmap_atomic(kaddr); -- 2.25.1