[RFC PATCH 42/57] mm/collapse: allow error injection into the freeze
From: Kiryl Shutsemau <hidden>
Date: 2026-08-16 22:47:37
Also in:
bpf, linux-kselftest, linux-mm, lkml
Subsystem:
memory management, the rest · Maintainers:
Andrew Morton, Linus Torvalds
From: "Kiryl Shutsemau (Meta)" <kas@kernel.org> The freeze refuses a candidate for reasons a test cannot arrange: a co-mapper appearing between the two sweeps, a GUP-fast pin, writeback. What the round does then -- the candidate drops out, its neighbours carry on, the region goes back to selection at a lower order -- is worth exercising on purpose. Tag collapse_freeze_candidate(), noinline so fail_function can find the symbol. ERRNO is the only injection type for a function that returns a value rather than a pointer or a bool, so an injected result is a negative errno. It only ever reaches cand->result, where every caller compares it against SCAN_SUCCEED and finds it unequal, which is the refusal the test wants. Tracing prints it as a number, having no symbol for it. A forced return happens at function entry, so this reaches the refusal, not the freeze's own unwind path. Assisted-by: Claude-Code:claude-opus-5 Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org> --- mm/collapse.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/mm/collapse.c b/mm/collapse.c
index 952e3f62d920..76a53616b240 100644
--- a/mm/collapse.c
+++ b/mm/collapse.c@@ -4,6 +4,7 @@ #include <linux/backing-dev.h> #include <linux/bitops.h> #include <linux/dax.h> +#include <linux/error-injection.h> #include <linux/highmem.h> #include <linux/huge_mm.h> #include <linux/hugetlb.h> /* x86 flush_tlb_range() uses hstate_vma() */
@@ -937,7 +938,7 @@ static enum scan_result collapse_check_candidate(struct vm_area_struct *vma, * collapse_freeze() issues the ranged TLB flush over everything that froze * before dropping the ptl. No copy may run before it completes. */ -static enum scan_result collapse_freeze_candidate(struct mm_struct *mm, +static noinline enum scan_result collapse_freeze_candidate(struct mm_struct *mm, struct collapse_candidate *cand, pte_t *pte) { const unsigned int nr_pages = candidate_nr_pages(cand);
@@ -1085,6 +1086,7 @@ static enum scan_result collapse_freeze_candidate(struct mm_struct *mm, collapse_unfreeze_candidate(mm, cand, pte, nr_saved, nr_frozen); return result; } +ALLOW_ERROR_INJECTION(collapse_freeze_candidate, ERRNO); /* * Raise the two barriers on the sources of every candidate: migration entries in
--
2.54.0