> On Aug 6, 2019, at 3:02 AM, Oleg Nesterov <oleg@xxxxxxxxxx> wrote: > > On 08/02, Song Liu wrote: >> >> +void collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr) >> +{ >> + unsigned long haddr = addr & HPAGE_PMD_MASK; >> + struct vm_area_struct *vma = find_vma(mm, haddr); >> + pmd_t *pmd = mm_find_pmd(mm, haddr); >> + struct page *hpage = NULL; >> + spinlock_t *ptl; >> + int count = 0; >> + pmd_t _pmd; >> + int i; >> + >> + if (!vma || !vma->vm_file || !pmd || >> + vma->vm_start > haddr || vma->vm_end < haddr + HPAGE_PMD_SIZE) >> + return; > > I still can't understand why is it safe to blindly use mm_find_pmd(). > > Say, what pmd_offset(pud, address) will return to this function if > pud_huge() == T? IIUC, this is possible if is_file_hugepages(vm_file). > How the code below can use this result? IIUC, the concern is matching files in hugetlbfs. Maybe we can exclude that specifically? > > I think you need something like hugepage_vma_check() or even > hugepage_vma_revalidate(). To use hugepage_vma_check(), we will need to set VM_HUGEPAGE for the following case: mount shm with huge=always copy app to shm start app and enable uprobe disable uprobe This vma will not have VM_HUGEPAGE, so it will fail hugepage_vma_check(). How about something like: diff --git i/kernel/events/uprobes.c w/kernel/events/uprobes.c index 94d38a39d72e..f0d3e367f907 100644 --- i/kernel/events/uprobes.c +++ w/kernel/events/uprobes.c @@ -532,8 +532,10 @@ int uprobe_write_opcode(struct arch_uprobe *auprobe, struct mm_struct *mm, put_page(new_page); new_page = NULL; - if (PageCompound(orig_page)) + if (PageCompound(orig_page)) { orig_page_huge = true; + vma->vm_flags |= VM_HUGEPAGE; + } } put_page(orig_page); } Thanks, Song