Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm, swap: fix swap cache index error when retrying reclaim

The allocator will reclaim cached slots while scanning. Currently, it
will try again if reclaim found a folio that is already removed from the
swap cache due to a race. But the following lookup will be using the
wrong index. It won't cause any OOB issue since the swap cache index is
truncated upon lookup, but it may lead to reclaiming of an irrelevant
folio.

This should not cause a measurable issue, but we should fix it.

Link: https://lkml.kernel.org/r/20250916160100.31545-4-ryncsn@gmail.com
Fixes: fae859550531 ("mm, swap: avoid reclaiming irrelevant swap cache")
Signed-off-by: Kairui Song <kasong@tencent.com>
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Acked-by: Nhat Pham <nphamcs@gmail.com>
Acked-by: Chris Li <chrisl@kernel.org>
Acked-by: David Hildenbrand <david@redhat.com>
Suggested-by: Chris Li <chrisl@kernel.org>
Cc: Baoquan He <bhe@redhat.com>
Cc: Barry Song <baohua@kernel.org>
Cc: "Huang, Ying" <ying.huang@linux.alibaba.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kemeng Shi <shikemeng@huaweicloud.com>
Cc: kernel test robot <oliver.sang@intel.com>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Yosry Ahmed <yosryahmed@google.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: SeongJae Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Kairui Song and committed by
Andrew Morton
a733d8de f2812461

+4 -4
+4 -4
mm/swapfile.c
··· 212 212 static int __try_to_reclaim_swap(struct swap_info_struct *si, 213 213 unsigned long offset, unsigned long flags) 214 214 { 215 - swp_entry_t entry = swp_entry(si->type, offset); 215 + const swp_entry_t entry = swp_entry(si->type, offset); 216 216 struct swap_cluster_info *ci; 217 217 struct folio *folio; 218 218 int ret, nr_pages; ··· 240 240 * Offset could point to the middle of a large folio, or folio 241 241 * may no longer point to the expected offset before it's locked. 242 242 */ 243 - entry = folio->swap; 244 - if (offset < swp_offset(entry) || offset >= swp_offset(entry) + nr_pages) { 243 + if (offset < swp_offset(folio->swap) || 244 + offset >= swp_offset(folio->swap) + nr_pages) { 245 245 folio_unlock(folio); 246 246 folio_put(folio); 247 247 goto again; 248 248 } 249 - offset = swp_offset(entry); 249 + offset = swp_offset(folio->swap); 250 250 251 251 need_reclaim = ((flags & TTRS_ANYWAY) || 252 252 ((flags & TTRS_UNMAPPED) && !folio_mapped(folio)) ||