The patch titled Subject: mm, rmap: check all VMAs that PTE-mapped THP can be part of has been added to the -mm tree. Its filename is mm-rmap-check-all-vmas-that-pte-mapped-thp-can-be-part-of.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/mm-rmap-check-all-vmas-that-pte-mapped-thp-can-be-part-of.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/mm-rmap-check-all-vmas-that-pte-mapped-thp-can-be-part-of.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/SubmitChecklist when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx> Subject: mm, rmap: check all VMAs that PTE-mapped THP can be part of Current rmap code can miss a VMA that maps PTE-mapped THP if the first suppage of the THP was unmapped from the VMA. We need to walk rmap for the whole range of offsets that THP covers, not only the first one. vma_address() also need to be corrected to check the range instead of the first subpage. Link: http://lkml.kernel.org/r/20170129173858.45174-6-kirill.shutemov@xxxxxxxxxxxxxxx Signed-off-by: Kirill A. Shutemov <kirill.shutemov@xxxxxxxxxxxxxxx> Acked-by: Hillf Danton <hillf.zj@xxxxxxxxxxxxxxx> Cc: Andrea Arcangeli <aarcange@xxxxxxxxxx> 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> Cc: Vladimir Davydov <vdavydov.dev@xxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/internal.h | 9 ++++++--- mm/rmap.c | 16 ++++++++++------ 2 files changed, 16 insertions(+), 9 deletions(-) diff -puN mm/internal.h~mm-rmap-check-all-vmas-that-pte-mapped-thp-can-be-part-of mm/internal.h --- a/mm/internal.h~mm-rmap-check-all-vmas-that-pte-mapped-thp-can-be-part-of +++ a/mm/internal.h @@ -335,12 +335,15 @@ __vma_address(struct page *page, struct static inline unsigned long vma_address(struct page *page, struct vm_area_struct *vma) { - unsigned long address = __vma_address(page, vma); + unsigned long start, end; + + start = __vma_address(page, vma); + end = start + PAGE_SIZE * (hpage_nr_pages(page) - 1); /* page should be within @vma mapping range */ - VM_BUG_ON_VMA(address < vma->vm_start || address >= vma->vm_end, vma); + VM_BUG_ON_VMA(end < vma->vm_start || start >= vma->vm_end, vma); - return address; + return max(start, vma->vm_start); } #else /* !CONFIG_MMU */ diff -puN mm/rmap.c~mm-rmap-check-all-vmas-that-pte-mapped-thp-can-be-part-of mm/rmap.c --- a/mm/rmap.c~mm-rmap-check-all-vmas-that-pte-mapped-thp-can-be-part-of +++ a/mm/rmap.c @@ -1757,7 +1757,7 @@ static int rmap_walk_anon(struct page *p bool locked) { struct anon_vma *anon_vma; - pgoff_t pgoff; + pgoff_t pgoff_start, pgoff_end; struct anon_vma_chain *avc; int ret = SWAP_AGAIN; @@ -1771,8 +1771,10 @@ static int rmap_walk_anon(struct page *p if (!anon_vma) return ret; - pgoff = page_to_pgoff(page); - anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, pgoff, pgoff) { + pgoff_start = page_to_pgoff(page); + pgoff_end = pgoff_start + hpage_nr_pages(page) - 1; + anon_vma_interval_tree_foreach(avc, &anon_vma->rb_root, + pgoff_start, pgoff_end) { struct vm_area_struct *vma = avc->vma; unsigned long address = vma_address(page, vma); @@ -1810,7 +1812,7 @@ static int rmap_walk_file(struct page *p bool locked) { struct address_space *mapping = page_mapping(page); - pgoff_t pgoff; + pgoff_t pgoff_start, pgoff_end; struct vm_area_struct *vma; int ret = SWAP_AGAIN; @@ -1825,10 +1827,12 @@ static int rmap_walk_file(struct page *p if (!mapping) return ret; - pgoff = page_to_pgoff(page); + pgoff_start = page_to_pgoff(page); + pgoff_end = pgoff_start + hpage_nr_pages(page) - 1; if (!locked) i_mmap_lock_read(mapping); - vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) { + vma_interval_tree_foreach(vma, &mapping->i_mmap, + pgoff_start, pgoff_end) { unsigned long address = vma_address(page, vma); cond_resched(); _ Patches currently in -mm which might be from kirill.shutemov@xxxxxxxxxxxxxxx are mm-sleeping-function-called-from-invalid-context-shmem_undo_range.patch mm-drop-zap_details-ignore_dirty.patch mm-drop-zap_details-check_swap_entries.patch mm-drop-unused-argument-of-zap_page_range.patch oom-reaper-use-madvise_dontneed-logic-to-decide-if-unmap-the-vma.patch uprobes-split-thps-before-trying-replace-them.patch mm-introduce-page_vma_mapped_walk.patch mm-fix-handling-pte-mapped-thps-in-page_referenced.patch mm-fix-handling-pte-mapped-thps-in-page_idle_clear_pte_refs.patch mm-rmap-check-all-vmas-that-pte-mapped-thp-can-be-part-of.patch mm-convert-page_mkclean_one-to-use-page_vma_mapped_walk.patch mm-convert-try_to_unmap_one-to-use-page_vma_mapped_walk.patch mm-ksm-convert-write_protect_page-to-use-page_vma_mapped_walk.patch mm-uprobes-convert-__replace_page-to-use-page_vma_mapped_walk.patch mm-convert-page_mapped_in_vma-to-use-page_vma_mapped_walk.patch mm-drop-page_check_address_transhuge.patch mm-convert-remove_migration_pte-to-use-page_vma_mapped_walk.patch -- 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