From: "Zi Yan" <ziy@nvidia.com>
To: "Kiryl Shutsemau" <kirill@shutemov.name>,
<akpm@linux-foundation.org>, <david@kernel.org>, <ljs@kernel.org>,
<hannes@cmpxchg.org>, <usama.arif@linux.dev>,
"Kairui Song" <kasong@tencent.com>
Cc: <lance.yang@linux.dev>, <hughd@google.com>,
<baolin.wang@linux.alibaba.com>, <baohua@kernel.org>,
<liam@infradead.org>, <nico.pache@linux.dev>, <dev.jain@arm.com>,
<ryan.roberts@arm.com>, <balbirs@nvidia.com>,
<linux-mm@kvack.org>, <linux-kernel@vger.kernel.org>,
"Kiryl Shutsemau (Meta)" <kas@kernel.org>
Subject: Re: [PATCH 2/5] mm/huge_memory: dequeue the deferred split after the split freeze
Date: Wed, 26 Aug 2026 13:10:33 -0400 [thread overview]
Message-ID: <DKZ1J2U9OT92.LM8445YM68HK@nvidia.com> (raw)
In-Reply-To: <20260826162101.1314941-3-kirill@shutemov.name>
On Wed Aug 26, 2026 at 12:20 PM EDT, Kiryl Shutsemau wrote:
> From: "Kiryl Shutsemau (Meta)" <kas@kernel.org>
>
> __folio_freeze_and_split_unmapped() takes the deferred split list_lru lock
> across the freeze. It is only there to stop deferred_split_scan() from
> touching the folio under split.
>
> With deferred_split_isolate() fixed, the workaround can be dropped.
>
> Unqueue the folio after folio_ref_freeze(), the way
> __folio_migrate_mapping() does: folio_unqueue_deferred_split() needs a
> zero refcount and a memcg still set, and both hold there.
>
> If the split is called from deferred_split_scan(), the unqueue is a
> no-op -- the folio is already removed from the list. But
> PG_partially_mapped is still set, so it has to be cleared here or
> MTHP_STAT_NR_ANON_PARTIALLY_MAPPED never comes back down.
>
> Assisted-by: Claude-Code:claude-opus-5
> Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
> ---
> mm/huge_memory.c | 44 +++++++++++++-------------------------------
> 1 file changed, 13 insertions(+), 31 deletions(-)
+Kairui, since the change affects his cleanup series. I assume this will
be picked up sooner than Kairui's large series.
>
> diff --git a/mm/huge_memory.c b/mm/huge_memory.c
> index 6281ed993243..c84e8cbc986d 100644
> --- a/mm/huge_memory.c
> +++ b/mm/huge_memory.c
> @@ -3931,41 +3931,27 @@ static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned int n
> struct folio *end_folio = folio_next(folio);
> struct folio *new_folio, *next;
> int old_order = folio_order(folio);
> - struct list_lru_one *lru;
> - bool dequeue_deferred;
> int ret = 0;
>
> VM_WARN_ON_ONCE(!mapping && end);
> - /*
> - * If this folio can be on the deferred split queue, lock out
> - * the shrinker before freezing the ref. If the shrinker sees
> - * a 0-ref folio, it assumes it beat folio_put() to the list
> - * lock and must clean up the LRU state - the same dequeue we
> - * will do below as part of the split.
> - */
> - dequeue_deferred = folio_test_anon(folio) && old_order > 1;
> - if (dequeue_deferred) {
> - struct mem_cgroup *memcg;
>
> - rcu_read_lock();
> - memcg = folio_memcg(folio);
> - lru = list_lru_lock(&deferred_split_lru,
> - folio_nid(folio), &memcg);
> - }
> if (folio_ref_freeze(folio, folio_cache_ref_count(folio) + 1)) {
> struct swap_cluster_info *ci = NULL;
> struct lruvec *lruvec;
>
> - if (dequeue_deferred) {
> - __list_lru_del(&deferred_split_lru, lru,
> - &folio->_deferred_list, folio_nid(folio));
> - if (folio_test_partially_mapped(folio)) {
> - folio_clear_partially_mapped(folio);
> - mod_mthp_stat(old_order,
> - MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1);
> - }
> - list_lru_unlock(lru);
> - rcu_read_unlock();
> + /* Take off the deferred split queue while frozen and memcg set */
> + folio_unqueue_deferred_split(folio);
> +
> + /*
> + * deferred_split_scan() takes the folio off the queue before it
> + * splits it, so the unqueue above finds an empty list and
> + * leaves PG_partially_mapped set.
> + * Clear it here: the flag does not survive the split.
> + */
> + if (folio_test_partially_mapped(folio)) {
> + folio_clear_partially_mapped(folio);
> + mod_mthp_stat(old_order,
> + MTHP_STAT_NR_ANON_PARTIALLY_MAPPED, -1);
> }
>
> if (mapping) {
> @@ -4067,10 +4053,6 @@ static int __folio_freeze_and_split_unmapped(struct folio *folio, unsigned int n
> if (ci)
> swap_cluster_unlock(ci);
> } else {
> - if (dequeue_deferred) {
> - list_lru_unlock(lru);
> - rcu_read_unlock();
> - }
> return -EAGAIN;
> }
>
This is a great cleanup. Thanks.
Reviewed-by: Zi Yan <ziy@nvidia.com>
--
Best Regards,
Yan, Zi
next prev parent reply other threads:[~2026-08-26 17:10 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-26 16:20 [PATCH 0/5] Fix deferred_split_isolate() and clean up __folio_freeze_and_split_unmapped() Kiryl Shutsemau
2026-08-26 16:20 ` [PATCH 1/5] mm/huge_memory: do not touch frozen folios in deferred_split_isolate() Kiryl Shutsemau
2026-08-26 16:45 ` Zi Yan
2026-08-27 15:02 ` Johannes Weiner
2026-08-27 15:23 ` David Hildenbrand (Arm)
2026-08-27 15:38 ` Zi Yan
2026-08-27 15:56 ` David Hildenbrand (Arm)
2026-08-27 16:38 ` Usama Arif
2026-08-28 1:57 ` Zi Yan
2026-08-31 0:33 ` Kiryl Shutsemau
2026-08-26 16:20 ` [PATCH 2/5] mm/huge_memory: dequeue the deferred split after the split freeze Kiryl Shutsemau
2026-08-26 17:10 ` Zi Yan [this message]
2026-08-27 15:25 ` David Hildenbrand (Arm)
2026-08-27 16:59 ` Johannes Weiner
2026-08-26 16:20 ` [PATCH 3/5] mm/huge_memory: reduce indent level in __folio_freeze_and_split_unmapped() Kiryl Shutsemau
2026-08-26 16:34 ` Zi Yan
2026-08-26 16:43 ` Kiryl Shutsemau
2026-08-26 16:21 ` [PATCH 4/5] mm/huge_memory: fold nested ifs " Kiryl Shutsemau
2026-08-26 16:21 ` [PATCH 5/5] mm/huge_memory: turn the swapcache-with-mapping error case into an assert Kiryl Shutsemau
2026-08-28 3:14 ` [PATCH 0/5] Fix deferred_split_isolate() and clean up __folio_freeze_and_split_unmapped() Balbir Singh
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=DKZ1J2U9OT92.LM8445YM68HK@nvidia.com \
--to=ziy@nvidia.com \
--cc=akpm@linux-foundation.org \
--cc=balbirs@nvidia.com \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=hannes@cmpxchg.org \
--cc=hughd@google.com \
--cc=kas@kernel.org \
--cc=kasong@tencent.com \
--cc=kirill@shutemov.name \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=nico.pache@linux.dev \
--cc=ryan.roberts@arm.com \
--cc=usama.arif@linux.dev \
/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.