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: check page poison flag after locking it

Instead of checking the poison flag only in the fast swap cache lookup
path, always check the poison flags after locking a swap cache folio.

There are two reasons to do so.

The folio is unstable and could be removed from the swap cache anytime, so
it's totally possible that the folio is no longer the backing folio of a
swap entry, and could be an irrelevant poisoned folio. We might
mistakenly kill a faulting process.

And it's totally possible or even common for the slow swap in path
(swapin_readahead) to bring in a cached folio. The cache folio could be
poisoned, too. Only checking the poison flag in the fast path will miss
such folios.

The race window is tiny, so it's very unlikely to happen, though. While
at it, also add a unlikely prefix.

Link: https://lkml.kernel.org/r/20250916160100.31545-5-ryncsn@gmail.com
Signed-off-by: Kairui Song <kasong@tencent.com>
Acked-by: Chris Li <chrisl@kernel.org>
Acked-by: David Hildenbrand <david@redhat.com>
Acked-by: Nhat Pham <nphamcs@gmail.com>
Suggested-by: Chris Li <chrisl@kernel.org>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
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
3518b931 a733d8de

+11 -11
+11 -11
mm/memory.c
··· 4661 4661 goto out; 4662 4662 4663 4663 folio = swap_cache_get_folio(entry); 4664 - if (folio) { 4664 + if (folio) 4665 4665 swap_update_readahead(folio, vma, vmf->address); 4666 - page = folio_file_page(folio, swp_offset(entry)); 4667 - } 4668 4666 swapcache = folio; 4669 4667 4670 4668 if (!folio) { ··· 4733 4735 ret = VM_FAULT_MAJOR; 4734 4736 count_vm_event(PGMAJFAULT); 4735 4737 count_memcg_event_mm(vma->vm_mm, PGMAJFAULT); 4736 - page = folio_file_page(folio, swp_offset(entry)); 4737 - } else if (PageHWPoison(page)) { 4738 - /* 4739 - * hwpoisoned dirty swapcache pages are kept for killing 4740 - * owner processes (which may be unknown at hwpoison time) 4741 - */ 4742 - ret = VM_FAULT_HWPOISON; 4743 - goto out_release; 4744 4738 } 4745 4739 4746 4740 ret |= folio_lock_or_retry(folio, vmf); 4747 4741 if (ret & VM_FAULT_RETRY) 4748 4742 goto out_release; 4749 4743 4744 + page = folio_file_page(folio, swp_offset(entry)); 4750 4745 if (swapcache) { 4751 4746 /* 4752 4747 * Make sure folio_free_swap() or swapoff did not release the ··· 4751 4760 if (unlikely(!folio_test_swapcache(folio) || 4752 4761 page_swap_entry(page).val != entry.val)) 4753 4762 goto out_page; 4763 + 4764 + if (unlikely(PageHWPoison(page))) { 4765 + /* 4766 + * hwpoisoned dirty swapcache pages are kept for killing 4767 + * owner processes (which may be unknown at hwpoison time) 4768 + */ 4769 + ret = VM_FAULT_HWPOISON; 4770 + goto out_page; 4771 + } 4754 4772 4755 4773 /* 4756 4774 * KSM sometimes has to copy on read faults, for example, if