unsigned long len, unsigned long pgoff, unsigned long flags,
                vm_flags_t vm_flags);
 
-bool can_split_folio(struct folio *folio, int *pextra_pins);
+bool can_split_folio(struct folio *folio, int caller_pins, int *pextra_pins);
 int split_huge_page_to_list_to_order(struct page *page, struct list_head *list,
                unsigned int new_order);
 static inline int split_huge_page(struct page *page)
 }
 
 static inline bool
-can_split_folio(struct folio *folio, int *pextra_pins)
+can_split_folio(struct folio *folio, int caller_pins, int *pextra_pins)
 {
        return false;
 }
 
 #include <linux/memory-tiers.h>
 #include <linux/compat.h>
 #include <linux/pgalloc_tag.h>
+#include <linux/pagewalk.h>
 
 #include <asm/tlb.h>
 #include <asm/pgalloc.h>
 }
 
 /* Racy check whether the huge page can be split */
-bool can_split_folio(struct folio *folio, int *pextra_pins)
+bool can_split_folio(struct folio *folio, int caller_pins, int *pextra_pins)
 {
        int extra_pins;
 
                extra_pins = folio_nr_pages(folio);
        if (pextra_pins)
                *pextra_pins = extra_pins;
-       return folio_mapcount(folio) == folio_ref_count(folio) - extra_pins - 1;
+       return folio_mapcount(folio) == folio_ref_count(folio) - extra_pins -
+                                       caller_pins;
 }
 
 /*
         * Racy check if we can split the page, before unmap_folio() will
         * split PMDs
         */
-       if (!can_split_folio(folio, &extra_pins)) {
+       if (!can_split_folio(folio, 1, &extra_pins)) {
                ret = -EAGAIN;
                goto out_unlock;
        }
         */
        for (addr = vaddr_start; addr < vaddr_end; addr += PAGE_SIZE) {
                struct vm_area_struct *vma = vma_lookup(mm, addr);
-               struct page *page;
+               struct folio_walk fw;
                struct folio *folio;
 
                if (!vma)
                        continue;
                }
 
-               /* FOLL_DUMP to ignore special (like zero) pages */
-               page = follow_page(vma, addr, FOLL_GET | FOLL_DUMP);
-
-               if (IS_ERR_OR_NULL(page))
+               folio = folio_walk_start(&fw, vma, addr, 0);
+               if (!folio)
                        continue;
 
-               folio = page_folio(page);
                if (!is_transparent_hugepage(folio))
                        goto next;
 
                 * can be split or not. So skip the check here.
                 */
                if (!folio_test_private(folio) &&
-                   !can_split_folio(folio, NULL))
+                   !can_split_folio(folio, 0, NULL))
                        goto next;
 
                if (!folio_trylock(folio))
                        goto next;
+               folio_get(folio);
+               folio_walk_end(&fw, vma);
 
                if (!split_folio_to_order(folio, new_order))
                        split++;
 
                folio_unlock(folio);
-next:
                folio_put(folio);
+
+               cond_resched();
+               continue;
+next:
+               folio_walk_end(&fw, vma);
                cond_resched();
        }
        mmap_read_unlock(mm);
 
                                        goto keep_locked;
                                if (folio_test_large(folio)) {
                                        /* cannot split folio, skip it */
-                                       if (!can_split_folio(folio, NULL))
+                                       if (!can_split_folio(folio, 1, NULL))
                                                goto activate_locked;
                                        /*
                                         * Split partially mapped folios right away.