Skip to content

Commit b93af2c

Browse files
sjp38akpm00
authored andcommitted
mm/damon/vaddr: do not repeat pte_offset_map_lock() until success
DAMON's virtual address space operation set implementation (vaddr) calls pte_offset_map_lock() inside the page table walk callback function. This is for reading and writing page table accessed bits. If pte_offset_map_lock() fails, it retries by returning the page table walk callback function with ACTION_AGAIN. pte_offset_map_lock() can continuously fail if the target is a pmd migration entry, though. Hence it could cause an infinite page table walk if the migration cannot be done until the page table walk is finished. This indeed caused a soft lockup when CPU hotplugging and DAMON were running in parallel. Avoid the infinite loop by simply not retrying the page table walk. DAMON is promising only a best-effort accuracy, so missing access to such pages is no problem. Link: https://lkml.kernel.org/r/[email protected] Fixes: 7780d04 ("mm/pagewalkers: ACTION_AGAIN if pte_offset_map_lock() fails") Signed-off-by: SeongJae Park <[email protected]> Reported-by: Xinyu Zheng <[email protected]> Closes: https://lore.kernel.org/[email protected] Acked-by: Hugh Dickins <[email protected]> Cc: <[email protected]> [6.5+] Signed-off-by: Andrew Morton <[email protected]>
1 parent 9658d69 commit b93af2c

File tree

1 file changed

+2
-6
lines changed

1 file changed

+2
-6
lines changed

mm/damon/vaddr.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,10 +328,8 @@ static int damon_mkold_pmd_entry(pmd_t *pmd, unsigned long addr,
328328
}
329329

330330
pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
331-
if (!pte) {
332-
walk->action = ACTION_AGAIN;
331+
if (!pte)
333332
return 0;
334-
}
335333
if (!pte_present(ptep_get(pte)))
336334
goto out;
337335
damon_ptep_mkold(pte, walk->vma, addr);
@@ -481,10 +479,8 @@ static int damon_young_pmd_entry(pmd_t *pmd, unsigned long addr,
481479
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
482480

483481
pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
484-
if (!pte) {
485-
walk->action = ACTION_AGAIN;
482+
if (!pte)
486483
return 0;
487-
}
488484
ptent = ptep_get(pte);
489485
if (!pte_present(ptent))
490486
goto out;

0 commit comments

Comments
 (0)