Skip to content

Commit 40b760c

Browse files
x-y-zakpm00
authored andcommitted
mm/numa: no task_numa_fault() call if PTE is changed
When handling a numa page fault, task_numa_fault() should be called by a process that restores the page table of the faulted folio to avoid duplicated stats counting. Commit b99a342 ("NUMA balancing: reduce TLB flush via delaying mapping on hint page fault") restructured do_numa_page() and did not avoid task_numa_fault() call in the second page table check after a numa migration failure. Fix it by making all !pte_same() return immediately. This issue can cause task_numa_fault() being called more than necessary and lead to unexpected numa balancing results (It is hard to tell whether the issue will cause positive or negative performance impact due to duplicated numa fault counting). Link: https://lkml.kernel.org/r/20240809145906.1513458-2-ziy@nvidia.com Fixes: b99a342 ("NUMA balancing: reduce TLB flush via delaying mapping on hint page fault") Signed-off-by: Zi Yan <ziy@nvidia.com> Reported-by: "Huang, Ying" <ying.huang@intel.com> Closes: https://lore.kernel.org/linux-mm/87zfqfw0yw.fsf@yhuang6-desk2.ccr.corp.intel.com/ Acked-by: David Hildenbrand <david@redhat.com> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Cc: Kefeng Wang <wangkefeng.wang@huawei.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Yang Shi <shy828301@gmail.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent 61ebe5a commit 40b760c

File tree

1 file changed

+16
-17
lines changed

1 file changed

+16
-17
lines changed

mm/memory.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5295,7 +5295,7 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
52955295

52965296
if (unlikely(!pte_same(old_pte, vmf->orig_pte))) {
52975297
pte_unmap_unlock(vmf->pte, vmf->ptl);
5298-
goto out;
5298+
return 0;
52995299
}
53005300

53015301
pte = pte_modify(old_pte, vma->vm_page_prot);
@@ -5358,23 +5358,19 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
53585358
if (!migrate_misplaced_folio(folio, vma, target_nid)) {
53595359
nid = target_nid;
53605360
flags |= TNF_MIGRATED;
5361-
} else {
5362-
flags |= TNF_MIGRATE_FAIL;
5363-
vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
5364-
vmf->address, &vmf->ptl);
5365-
if (unlikely(!vmf->pte))
5366-
goto out;
5367-
if (unlikely(!pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
5368-
pte_unmap_unlock(vmf->pte, vmf->ptl);
5369-
goto out;
5370-
}
5371-
goto out_map;
5361+
task_numa_fault(last_cpupid, nid, nr_pages, flags);
5362+
return 0;
53725363
}
53735364

5374-
out:
5375-
if (nid != NUMA_NO_NODE)
5376-
task_numa_fault(last_cpupid, nid, nr_pages, flags);
5377-
return 0;
5365+
flags |= TNF_MIGRATE_FAIL;
5366+
vmf->pte = pte_offset_map_lock(vma->vm_mm, vmf->pmd,
5367+
vmf->address, &vmf->ptl);
5368+
if (unlikely(!vmf->pte))
5369+
return 0;
5370+
if (unlikely(!pte_same(ptep_get(vmf->pte), vmf->orig_pte))) {
5371+
pte_unmap_unlock(vmf->pte, vmf->ptl);
5372+
return 0;
5373+
}
53785374
out_map:
53795375
/*
53805376
* Make it present again, depending on how arch implements
@@ -5387,7 +5383,10 @@ static vm_fault_t do_numa_page(struct vm_fault *vmf)
53875383
numa_rebuild_single_mapping(vmf, vma, vmf->address, vmf->pte,
53885384
writable);
53895385
pte_unmap_unlock(vmf->pte, vmf->ptl);
5390-
goto out;
5386+
5387+
if (nid != NUMA_NO_NODE)
5388+
task_numa_fault(last_cpupid, nid, nr_pages, flags);
5389+
return 0;
53915390
}
53925391

53935392
static inline vm_fault_t create_huge_pmd(struct vm_fault *vmf)

0 commit comments

Comments
 (0)