Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux
[linux-drm-fsl-dcu.git] / mm / page_idle.c
index d5dd79041484588cdfb409e7610d9ea23ee3c370..4ea9c4ef5146b8b784848a6710b70e5fc0dfcd41 100644 (file)
@@ -55,25 +55,26 @@ static int page_idle_clear_pte_refs_one(struct page *page,
                                        unsigned long addr, void *arg)
 {
        struct mm_struct *mm = vma->vm_mm;
-       spinlock_t *ptl;
        pmd_t *pmd;
        pte_t *pte;
+       spinlock_t *ptl;
        bool referenced = false;
 
-       if (unlikely(PageTransHuge(page))) {
-               pmd = page_check_address_pmd(page, mm, addr,
-                                            PAGE_CHECK_ADDRESS_PMD_FLAG, &ptl);
-               if (pmd) {
-                       referenced = pmdp_clear_young_notify(vma, addr, pmd);
-                       spin_unlock(ptl);
-               }
+       if (!page_check_address_transhuge(page, mm, addr, &pmd, &pte, &ptl))
+               return SWAP_AGAIN;
+
+       if (pte) {
+               referenced = ptep_clear_young_notify(vma, addr, pte);
+               pte_unmap(pte);
+       } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
+               referenced = pmdp_clear_young_notify(vma, addr, pmd);
        } else {
-               pte = page_check_address(page, mm, addr, &ptl, 0);
-               if (pte) {
-                       referenced = ptep_clear_young_notify(vma, addr, pte);
-                       pte_unmap_unlock(pte, ptl);
-               }
+               /* unexpected pmd-mapped page? */
+               WARN_ON_ONCE(1);
        }
+
+       spin_unlock(ptl);
+
        if (referenced) {
                clear_page_idle(page);
                /*