From: "Kiryl Shutsemau (Meta)" <[email protected]>

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) <[email protected]>
---
 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


Reply via email to