madvise: convert madvise_free_pte_range() to use a folio
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Fri, 2 Sep 2022 19:46:39 +0000 (20:46 +0100)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 3 Oct 2022 21:02:52 +0000 (14:02 -0700)
Saves a lot of calls to compound_head().

Link: https://lkml.kernel.org/r/20220902194653.1739778-44-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/madvise.c

index a3fc4cd32ed364dafa78712f98f13bd054ef8624..2baa93ca2310967ba897146480e4a7d6b86f4203 100644 (file)
@@ -601,6 +601,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
        struct vm_area_struct *vma = walk->vma;
        spinlock_t *ptl;
        pte_t *orig_pte, *pte, ptent;
+       struct folio *folio;
        struct page *page;
        int nr_swap = 0;
        unsigned long next;
@@ -645,56 +646,56 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
                page = vm_normal_page(vma, addr, ptent);
                if (!page || is_zone_device_page(page))
                        continue;
+               folio = page_folio(page);
 
                /*
-                * If pmd isn't transhuge but the page is THP and
+                * If pmd isn't transhuge but the folio is large and
                 * is owned by only this process, split it and
                 * deactivate all pages.
                 */
-               if (PageTransCompound(page)) {
-                       if (page_mapcount(page) != 1)
+               if (folio_test_large(folio)) {
+                       if (folio_mapcount(folio) != 1)
                                goto out;
-                       get_page(page);
-                       if (!trylock_page(page)) {
-                               put_page(page);
+                       folio_get(folio);
+                       if (!folio_trylock(folio)) {
+                               folio_put(folio);
                                goto out;
                        }
                        pte_unmap_unlock(orig_pte, ptl);
-                       if (split_huge_page(page)) {
-                               unlock_page(page);
-                               put_page(page);
+                       if (split_folio(folio)) {
+                               folio_unlock(folio);
+                               folio_put(folio);
                                orig_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
                                goto out;
                        }
-                       unlock_page(page);
-                       put_page(page);
+                       folio_unlock(folio);
+                       folio_put(folio);
                        orig_pte = pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
                        pte--;
                        addr -= PAGE_SIZE;
                        continue;
                }
 
-               VM_BUG_ON_PAGE(PageTransCompound(page), page);
-
-               if (PageSwapCache(page) || PageDirty(page)) {
-                       if (!trylock_page(page))
+               if (folio_test_swapcache(folio) || folio_test_dirty(folio)) {
+                       if (!folio_trylock(folio))
                                continue;
                        /*
-                        * If page is shared with others, we couldn't clear
-                        * PG_dirty of the page.
+                        * If folio is shared with others, we mustn't clear
+                        * the folio's dirty flag.
                         */
-                       if (page_mapcount(page) != 1) {
-                               unlock_page(page);
+                       if (folio_mapcount(folio) != 1) {
+                               folio_unlock(folio);
                                continue;
                        }
 
-                       if (PageSwapCache(page) && !try_to_free_swap(page)) {
-                               unlock_page(page);
+                       if (folio_test_swapcache(folio) &&
+                           !folio_free_swap(folio)) {
+                               folio_unlock(folio);
                                continue;
                        }
 
-                       ClearPageDirty(page);
-                       unlock_page(page);
+                       folio_clear_dirty(folio);
+                       folio_unlock(folio);
                }
 
                if (pte_young(ptent) || pte_dirty(ptent)) {
@@ -712,7 +713,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
                        set_pte_at(mm, addr, pte, ptent);
                        tlb_remove_tlb_entry(tlb, pte, addr);
                }
-               mark_page_lazyfree(page);
+               mark_page_lazyfree(&folio->page);
        }
 out:
        if (nr_swap) {