Re: [PATCH v3 01/18] mm/swap: fix off-by-one in swap cache replace sanity check
From: Kiryl Shutsemau
Date: Thu Aug 27 2026 - 10:13:44 EST
On Fri, Aug 21, 2026 at 02:55:14AM +0800, Kairui Song via B4 Relay wrote:
> 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>
Acked-by: Kiryl Shutsemau (Meta) <kas@xxxxxxxxxx>
> ---
> 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 b76eb3d876fd..59a577f685b5 100644
> --- a/mm/swap_state.c
> +++ b/mm/swap_state.c
> @@ -389,8 +389,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);
I don't particularly like increment mixed with condition, but it seems
to be consistent with other swap code...
> }
> }
>
>
> --
> 2.55.0
>
>
--
Kiryl Shutsemau / Kirill A. Shutemov