From: Shao Mingyin mm/migrate: fix softlockup in do_pages_move() with huge page arrays do_pages_move() walks the user page array one page at a time. For each entry it performs two get_user() calls, an mmap_read_lock()/unlock() around a folio walk, and an optional store_status(); none of them has to sleep when the arrays stay resident and the rwsem is uncontended. move_pages_and_store_status() returns early while the page list is empty, so an array whose entries all resolve to the same node can run the whole loop without any scheduling point. nr_pages comes straight from move_pages(), so a huge array can hold a CPU past the watchdog threshold on a non-preemptible kernel; with KASAN and function tracing enabled, ten million entries can exceed it. Add cond_resched() so that long calls yield periodically. do_pages_stat() has the same problem and is being fixed separately. In current mainline only alpha, hexagon and classic m68k can still select PREEMPT_NONE, and they cannot enable CONFIG_NUMA, so this mainly targets pre-v7.0 stable kernels. Fixes: a49bd4d71637 ("mm, numa: rework do_pages_move") Cc: stable@vger.kernel.org Signed-off-by: Shao Mingyin --- mm/migrate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm/migrate.c b/mm/migrate.c index 875079464930..3122ecb85270 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -2372,6 +2372,8 @@ static int do_pages_move(struct mm_struct *mm, nodemask_t task_nodes, const void __user *p; int node; + cond_resched(); + err = -EFAULT; if (in_compat_syscall()) { compat_uptr_t cp;