All of lore.kernel.org
 help / color / mirror / Atom feed
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



  reply	other threads:[~2026-08-19 12:52 UTC|newest]

Thread overview: 31+ 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 12:31     ` Usama Arif
2026-08-19 14:42       ` Kiryl Shutsemau
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-18 13:09 ` [PATCH v6 04/12] mm: handle PMD swap entries in fork path Usama Arif
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.