From: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx> Subject: mm: fix handling PTE-mapped THPs in page_idle_clear_pte_refs() For PTE-mapped THP page_check_address_transhuge() is not adequate: it cannot find all relevant PTEs, only the first one.i Let's switch it to page_vma_mapped_walk(). I don't think it's subject for stable@: it's not fatal. Link: http://lkml.kernel.org/r/20170129173858.45174-5-kirill.shutemov@xxxxxxxxxxxxxxx Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> Cc: Vladimir Davydov <vdavydov.dev@xxxxxxxxx> Cc: Andrea Arcangeli <aarcange@xxxxxxxxxx> Cc: Hillf Danton <hillf.zj@xxxxxxxxxxxxxxx> Cc: Hugh Dickins <hughd@xxxxxxxxxx> Cc: Johannes Weiner <hannes@xxxxxxxxxxx> Cc: Oleg Nesterov <oleg@xxxxxxxxxx> Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx> Cc: Rik van Riel <riel@xxxxxxxxxx> Cc: Srikar Dronamraju <srikar@xxxxxxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/page_idle.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff -puN mm/page_idle.c~mm-fix-handling-pte-mapped-thps-in-page_idle_clear_pte_refs mm/page_idle.c --- a/mm/page_idle.c~mm-fix-handling-pte-mapped-thps-in-page_idle_clear_pte_refs +++ a/mm/page_idle.c @@ -54,27 +54,27 @@ static int page_idle_clear_pte_refs_one( struct vm_area_struct *vma, unsigned long addr, void *arg) { - struct mm_struct *mm = vma->vm_mm; - pmd_t *pmd; - pte_t *pte; - spinlock_t *ptl; + struct page_vma_mapped_walk pvmw = { + .page = page, + .vma = vma, + .address = addr, + }; bool referenced = false; - 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 { - /* unexpected pmd-mapped page? */ - WARN_ON_ONCE(1); + while (page_vma_mapped_walk(&pvmw)) { + addr = pvmw.address; + if (pvmw.pte) { + referenced = ptep_clear_young_notify(vma, addr, + pvmw.pte); + } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) { + referenced = pmdp_clear_young_notify(vma, addr, + pvmw.pmd); + } else { + /* unexpected pmd-mapped page? */ + WARN_ON_ONCE(1); + } } - spin_unlock(ptl); - if (referenced) { clear_page_idle(page); /* _ -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html