From: Usama Arif <usama.arif@linux.dev>
To: Lance Yang <lance.yang@linux.dev>
Cc: akpm@linux-foundation.org, david@kernel.org, chrisl@kernel.org,
kasong@tencent.com, ljs@kernel.org, ziy@nvidia.com,
linux-mm@kvack.org, ying.huang@linux.alibaba.com,
baoquan.he@linux.dev, willy@infradead.org, youngjun.park@lge.com,
hannes@cmpxchg.org, riel@surriel.com, shakeel.butt@linux.dev,
alex@ghiti.fr, kas@kernel.org, baohua@kernel.org,
dev.jain@arm.com, baolin.wang@linux.alibaba.com,
nico.pache@linux.dev, liam@infradead.org, ryan.roberts@arm.com,
vbabka@kernel.org, linux-kernel@vger.kernel.org,
nphamcs@gmail.com, shikemeng@huaweicloud.com, yosry@kernel.org,
kernel-team@meta.com, linmiaohe@huawei.com
Subject: Re: [PATCH v6 06/12] mm: swap in PMD swap entries as whole THPs during swapoff
Date: Wed, 19 Aug 2026 13:52:46 +0100 [thread overview]
Message-ID: <a2dc0b6c-2225-49d5-a24f-4a54c9262f2d@linux.dev> (raw)
In-Reply-To: <20260819053803.15868-1-lance.yang@linux.dev>
On 19/08/2026 06:38, Lance Yang wrote:
> +Cc Miaohe
>
> On Tue, Aug 18, 2026 at 06:09:47AM -0700, Usama Arif wrote:
> [...]
>> +#ifdef CONFIG_THP_SWAP
>> +/*
>> + * unuse_pmd - Map a locked folio at PMD granularity during swapoff.
>> + *
>> + * The caller provides a locked, swapped-in folio. Returns 0 on success
>> + * (PMD was mapped). Returns -EAGAIN if the swap cache folio no longer
>> + * matches the entry or the PMD changed under the lock (try_to_unuse will
>> + * rescan). Returns -EIO if the folio is not uptodate or contains a poisoned
>> + * subpage; in that case the PMD is split so unuse_pte_range() can handle
>> + * individual pages.
>> + */
>> +static int unuse_pmd(struct vm_area_struct *vma, pmd_t *pmd,
>> + unsigned long addr, softleaf_t entry,
>> + struct folio *folio)
>> +{
>> + struct mm_struct *mm = vma->vm_mm;
>> + struct page *page;
>> + pmd_t new_pmd, old_pmd;
>> + spinlock_t *ptl;
>> + rmap_t rmap_flags = RMAP_NONE;
>> + bool exclusive;
>> +
>> + if (unlikely(!folio_matches_swap_entry(folio, entry)))
>> + return -EAGAIN;
>> +
>> + if (unlikely(!folio_test_uptodate(folio))) {
>> + /* Let PTE fallback reread each slot independently. */
>> + swap_cache_del_folio(folio);
>> + __split_huge_pmd(vma, pmd, addr, false);
>> + return -EIO;
>> + }
>> +
>> + if (unlikely(folio_contain_hwpoisoned_page(folio))) {
>> + /* Let PTE fallback isolate the poisoned subpages. */
>> + __split_huge_pmd(vma, pmd, addr, false);
>> + return -EIO;
>> + }
>
> Hmm ... can this miss a poisoned tail?
>
> memory_failure() sets PageHWPoison(p) before taking folio_lock(), but
> PG_has_hwpoisoned is only set later. Since unuse_pmd_entry() holds folio
> lock across this check, memory_failure() can be blocked on folio_lock()
> with a tail already poisoned, IIUC ...
>
> folio_contain_hwpoisoned_page() then sees neither a poisoned head nor
> PG_has_hwpoisoned, and set_pmd_at() maps that tail through a normal PMD.
>
> Note that unuse_pte() checks PageHWPoison(page) directly. Should we check
> each subpage here as well before installing the PMD?
Good catch!
I am going to introduce a helper like below and use it in the next
revision. Thanks!
static inline bool folio_has_hwpoisoned_subpage(struct folio *folio)
{
unsigned long i;
for (i = 0; i < folio_nr_pages(folio); i++)
if (PageHWPoison(folio_page(folio, i)))
return true;
return false;
}
>
>> +
>> + page = folio_page(folio, 0);
>> +
>> + ptl = pmd_lock(mm, pmd);
>> + old_pmd = pmdp_get(pmd);
>> +
>> + if (!pmd_is_swap_entry(old_pmd) ||
>> + softleaf_from_pmd(old_pmd).val != entry.val) {
>> + spin_unlock(ptl);
>> + return -EAGAIN;
>> + }
>> +
>> + exclusive = pmd_swp_exclusive(old_pmd);
>> +
>> + /*
>> + * Some architectures may have to restore extra metadata to the folio
>> + * when reading from swap. This metadata may be indexed by swap entry
>> + * so this must be called before folio_put_swap().
>> + */
>> + arch_swap_restore(folio_swap(entry, folio), folio);
>> +
>> + add_mm_counter(mm, MM_ANONPAGES, HPAGE_PMD_NR);
>> + add_mm_counter(mm, MM_SWAPENTS, -HPAGE_PMD_NR);
>> +
>> + new_pmd = folio_mk_pmd(folio, vma->vm_page_prot);
>> + new_pmd = pmd_mkold(new_pmd);
>> + if (pmd_swp_soft_dirty(old_pmd))
>> + new_pmd = pmd_mksoft_dirty(new_pmd);
>> + if (pmd_swp_uffd(old_pmd))
>> + new_pmd = pmd_mkuffd(new_pmd);
>> + if (pmd_swp_uffd(old_pmd) && userfaultfd_rwp(vma))
>> + new_pmd = pmd_modify(new_pmd, PAGE_NONE);
>> +
>> + if (exclusive)
>> + rmap_flags |= RMAP_EXCLUSIVE;
>> +
>> + folio_get(folio);
>> + if (!folio_test_anon(folio))
>> + folio_add_new_anon_rmap(folio, vma, addr, rmap_flags);
>> + else
>> + folio_add_anon_rmap_pmd(folio, page, vma, addr, rmap_flags);
>> +
>> + set_pmd_at(mm, addr, pmd, new_pmd);
>> + folio_put_swap(folio, NULL);
>> +
>> + spin_unlock(ptl);
>> +
>> + folio_free_swap(folio);
>> + return 0;
>> +}
>
> [...]
>
> Cheers, Lance
next prev parent reply other threads:[~2026-08-19 12:52 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-18 13:09 [PATCH v6 00/12] mm: PMD-level swap entries for anonymous THPs Usama Arif
2026-08-18 13:09 ` [PATCH v6 01/12] mm: rename pmd_to_softleaf_folio() to pmd_softleaf_to_folio() Usama Arif
2026-08-18 14:24 ` David Hildenbrand (Arm)
2026-08-18 18:36 ` Lorenzo Stoakes (ARM)
2026-08-18 18:38 ` Zi Yan
2026-08-19 14:32 ` Kiryl Shutsemau
2026-08-18 13:09 ` [PATCH v6 02/12] mm: add PMD swap entry detection support Usama Arif
2026-08-18 14:40 ` David Hildenbrand (Arm)
2026-08-18 18:42 ` Lorenzo Stoakes (ARM)
2026-08-19 12:33 ` Usama Arif
2026-08-19 16:05 ` David Hildenbrand (Arm)
2026-08-19 12:31 ` Usama Arif
2026-08-19 14:42 ` Kiryl Shutsemau
2026-08-19 16:00 ` David Hildenbrand (Arm)
2026-08-18 13:09 ` [PATCH v6 03/12] mm: add PMD swap entry splitting support Usama Arif
2026-08-18 17:53 ` David Hildenbrand (Arm)
2026-08-19 12:39 ` Usama Arif
2026-08-19 16:05 ` David Hildenbrand (Arm)
2026-08-19 15:16 ` Kiryl Shutsemau
2026-08-19 16:04 ` David Hildenbrand (Arm)
2026-08-19 15:13 ` Kiryl Shutsemau
2026-08-18 13:09 ` [PATCH v6 04/12] mm: handle PMD swap entries in fork path Usama Arif
2026-08-19 15:46 ` Kiryl Shutsemau
2026-08-18 13:09 ` [PATCH v6 05/12] mm: zswap: add range lookup for large-folio swapin Usama Arif
2026-08-18 18:28 ` Yosry Ahmed
2026-08-19 12:50 ` Usama Arif
2026-08-18 13:09 ` [PATCH v6 06/12] mm: swap in PMD swap entries as whole THPs during swapoff Usama Arif
2026-08-19 5:38 ` Lance Yang
2026-08-19 12:52 ` Usama Arif [this message]
2026-08-18 13:09 ` [PATCH v6 07/12] mm: handle PMD swap entries in non-present PMD walkers Usama Arif
2026-08-18 13:09 ` [PATCH v6 08/12] mm: handle PMD swap entries in MADV_WILLNEED Usama Arif
2026-08-18 13:09 ` [PATCH v6 09/12] mm: handle PMD swap entries in UFFDIO_MOVE Usama Arif
2026-08-18 13:09 ` [PATCH v6 10/12] mm: handle PMD swap entry faults on swap-in Usama Arif
2026-08-18 13:09 ` [PATCH v6 11/12] mm: install PMD swap entries on swap-out Usama Arif
2026-08-18 13:09 ` [PATCH v6 12/12] selftests/mm: add PMD swap entry tests Usama Arif
2026-08-19 10:10 ` Lance Yang
2026-08-19 12:56 ` Usama Arif
2026-08-19 13:04 ` [PATCH v6 00/12] mm: PMD-level swap entries for anonymous THPs Usama Arif
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=a2dc0b6c-2225-49d5-a24f-4a54c9262f2d@linux.dev \
--to=usama.arif@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=alex@ghiti.fr \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=baoquan.he@linux.dev \
--cc=chrisl@kernel.org \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=hannes@cmpxchg.org \
--cc=kas@kernel.org \
--cc=kasong@tencent.com \
--cc=kernel-team@meta.com \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linmiaohe@huawei.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=nico.pache@linux.dev \
--cc=nphamcs@gmail.com \
--cc=riel@surriel.com \
--cc=ryan.roberts@arm.com \
--cc=shakeel.butt@linux.dev \
--cc=shikemeng@huaweicloud.com \
--cc=vbabka@kernel.org \
--cc=willy@infradead.org \
--cc=ying.huang@linux.alibaba.com \
--cc=yosry@kernel.org \
--cc=youngjun.park@lge.com \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox