[PATCH v2 01/17] mm/swap: fix off-by-one in swap cache replace sanity check
From: Kairui Song via B4 Relay
Date: Wed Aug 12 2026 - 14:49:17 EST
From: Kairui Song <kasong@xxxxxxxxxxx>
The DEBUG_VM sanity check in __swap_cache_replace_folio() iterates
the old folio's range with "while (ci_off++ < ci_end)", so the loop
body runs on the already-incremented offset: the first entry is
skipped and one entry past the range is read. For a folio split
that entry belongs to the first after-split folio and was just
repointed by the replacement loop above, so the check would warn
spuriously whenever sub-folio orders differ from the head folio's,
as non-uniform swapcache splits now do.
Use the same do-while pattern as the replacement loop.
Fixes: 8578e0c00dcf ("mm, swap: use the swap table for the swap cache and switch API")
Acked-by: Zi Yan <ziy@xxxxxxxxxx>
Signed-off-by: Kairui Song <kasong@xxxxxxxxxxx>
---
mm/swap_state.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 5be825911e64..f1405e5b813e 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -388,8 +388,9 @@ void __swap_cache_replace_folio(struct swap_cluster_info *ci,
folio_order(old) != folio_order(new)) {
ci_off = swp_cluster_offset(old->swap);
ci_end = ci_off + folio_nr_pages(old);
- while (ci_off++ < ci_end)
+ do {
WARN_ON_ONCE(swp_tb_to_folio(__swap_table_get(ci, ci_off)) != old);
+ } while (++ci_off < ci_end);
}
}
--
2.55.0