mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Ilya Gladyshev" <ilya.gladyshev@linux.dev>
To: "Zi Yan" <ziy@nvidia.com>
Cc: akpm@linux-foundation.org, andrew+netdev@lunn.ch,
	apopple@nvidia.com, artem.kuzin@huawei.com,
	baolin.wang@linux.alibaba.com, david@kernel.org,
	Liam.Howlett@oracle.com, edumazet@google.com,
	harry.yoo@oracle.com, hramamurthy@google.com, ivgorbunov@me.com,
	joshwash@google.com, kirill@shutemov.name,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	lorenzo.stoakes@oracle.com, mhocko@suse.com,
	muchun.song@linux.dev, pfalcato@suse.de, rppt@kernel.org,
	surenb@google.com, torvalds@linuxfoundation.org, vbabka@suse.cz,
	willy@infradead.org, yuzhao@google.com, ilya.gladyshev@linux.dev
Subject: Re: [PATCH v6 3/3] mm: implement page refcount locking via dedicated bit
Date: Wed, 23 Sep 2026 17:34:27 +0000	[thread overview]
Message-ID: <56e036665dbeb0a8f51d697220d5ed84f210994c@linux.dev> (raw)
In-Reply-To: <DLFJL5U9DI6F.3QJP9YP0KX636@nvidia.com>

September 15, 2026 at 5:42 AM, "Zi Yan" <ziy@nvidia.com mailto:ziy@nvidia.com?to=%22Zi%20Yan%22%20%3Cziy%40nvidia.com%3E > wrote:


> 
> On Sat Sep 12, 2026 at 3:50 PM EDT, Ilya Gladyshev wrote:
> 
> > 
> > The current page refcount implementation uses a single counter value
> >  (zero) as dead. So, to prevent incrementing a dead refcount in
> >  folio_try_get(), it fundamentally requires a CAS loop.
> > 
> >  This CAS loop can act as a serialization point and can become a
> >  significant bottleneck during high-frequency file read operations
> >  [1][2].
> > 
> >  This patch reallocates the refcount value range:
> > 
> >  (1) refcount < 0 means dead refcount (uninit / frozen)
> >  (2) refcount = 0 allowed only as a temporary state (see below)
> >  (3) refcount > 0 is a regular reference count
> > 
> >  In other words, refcount is now split into "dead bit" and a 31-bit
> >  counter.
> > 
> >  Refcount decrement now works as follows:
> >  1. Counter decrement
> >  2. If it is now zero, try to put it deep inside the dead zone
> >  (CAS to INT_MIN). Or you can view it as "set up frozen bit and reset
> >  counter".
> >  3. This CAS can fail only if someone grabbed a reference in-between --
> >  that's okay, this page is their problem now.
> > 
> I am not sure this works. David raised a concern on V4[1], where if a
> folio lands to page_frag_free()'s free_frozen_pages(), it will not be
> properly handled. "this page is their problem" only works if every
> folio/page free functions call a generic folio/page free function that
> checks the page type and does the proper handling.

>> Refcount decrement now works as follows:
>> 1. Counter decrement
>> 2. If it is now zero, try to put it deep inside the dead zone
>>     (CAS to INT_MIN). Or you can view it as "set up frozen bit and reset
>>     counter".
>> 3. This CAS can fail only if someone grabbed a reference in-between --
>>     that's okay, this page is their problem now.
>
> I am not sure this works. David raised a concern on V4[1], where if a
> folio lands to page_frag_free()'s free_frozen_pages(), it will not be
> properly handled. "this page is their problem" only works if every
> folio/page free functions call a generic folio/page free function that
> checks the page type and does the proper handling.

After some thinking, this scenario is indeed possible and problematic. The
complexity of the required setup give me hope that there are some implicit
barriers, however I wasn't able to find them. But I am not an mm guru,
so maybe I missed something :shrug:

-- Below is a minimal buggy scenario --

Thread A: network code that calls page_frag_free()
Thread B: calls folio_try_get(). Maybe it is the DAMON paddr scanner,
          maybe this folio was previously used in page cache
          (however this noticeably complicates the scenario)
Thread C: user of folio's reincarnation. It also requires destruction via
          folio_put() and not via free_frozen_pages() -- for example hugetlb
          or memcg charged folio.

Refcount operations as follows (FR = FROZEN):

A: DEC 1 -> 0  [ page_ref_dec_and_test() ]
B: INC 0 -> 1  [ folio_try_get() ] => success
B: DEC 1 -> 0  [ page_ref_dec_and_test() ]
B: CAS 0 -> FR [ page_ref_dec_and_test() ]
B: * deallocates via __folio_put() *

C: * re-allocates page *
C: DEC 1 -> 0  [ page_ref_dec_and_test() ]
A: CAS 0 -> FR [ page_ref_dec_and_test() ] => success
A: * deallocates directly via free_frozen_pages() * => BUG

This can be fixed with a `s/page_frag_free/folio_put/`-style patch, however
it seems unreasonable...


> Before your patches, only a speculative page getter can see any page and
> folio_put() handles the last reference drop. So it is safe today.
> 
> Let me know if I miss anything.
> 
> [1] https://lore.kernel.org/linux-mm/086b119c-b777-46ae-b087-798ca3e44ecd@kernel.org/
> 
> > 
> > The size of the dead zone allows performing an optimistic increment
> >  inside page_ref_add_unless_frozen(), replacing the previous read + CAS
> >  loop with a single RMW operation. This reduces cache line bouncing and
> >  improves scalability, especially in NUMA scenarios.
> > 
> >  [1]: https://lore.kernel.org/all/20251017141536.577466-1-kirill@shutemov.name/
> >  [2]: https://lore.kernel.org/all/CAHk-=wj00-nGmXEkxY=-=Z_qP6kiGUziSFvxHJ9N-cLWry5zpA@mail.gmail.com/
> > 
> >  Reviewed-by: Artem Kuzin <artem.kuzin@huawei.com>
> >  Co-developed-by: Ivan Gorbunov <ivgorbunov@me.com>
> >  Signed-off-by: Ivan Gorbunov <ivgorbunov@me.com>
> >  Signed-off-by: Ilya Gladyshev <ilya.gladyshev@linux.dev>
> >  Acked-by: Linus Torvalds <torvalds@linuxfoundation.org>
> >  ---
> >  include/linux/page-flags.h | 13 +++++++++++++
> >  include/linux/page_ref.h | 30 +++++++++++++++++++++++++-----
> >  2 files changed, 38 insertions(+), 5 deletions(-)
> > 
> -- 
> Best Regards,
> Yan, Zi
>

---
Ilya Gladyshev // foxido.dev

  reply	other threads:[~2026-09-23 17:34 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-12 19:50 [PATCH v6 0/3] mm: improve folio refcount scalability Ilya Gladyshev
2026-09-12 19:50 ` [PATCH v6 1/3] gve: reduce pagecnt_bias to USHRT_MAX Ilya Gladyshev
2026-09-12 19:50 ` [PATCH v6 2/3] mm: drop page refcount zero state semantics Ilya Gladyshev
2026-09-14  9:13   ` Kiryl Shutsemau
2026-09-12 19:50 ` [PATCH v6 3/3] mm: implement page refcount locking via dedicated bit Ilya Gladyshev
2026-09-14 10:39   ` Kiryl Shutsemau
2026-09-15  2:42   ` Zi Yan
2026-09-23 17:34     ` Ilya Gladyshev [this message]
2026-09-24 18:51       ` David Hildenbrand (Arm)
2026-09-24 20:06         ` Linus Torvalds
2026-09-25  2:44           ` Zi Yan
2026-09-25  7:03             ` Ilya Gladyshev
2026-09-25  7:06               ` David Hildenbrand (Arm)
2026-09-25  7:15             ` David Hildenbrand (Arm)
2026-09-14  0:06 ` [PATCH v6 0/3] mm: improve folio refcount scalability Andrew Morton
2026-09-14  8:10   ` Ilya Gladyshev

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=56e036665dbeb0a8f51d697220d5ed84f210994c@linux.dev \
    --to=ilya.gladyshev@linux.dev \
    --cc=Liam.Howlett@oracle.com \
    --cc=akpm@linux-foundation.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=apopple@nvidia.com \
    --cc=artem.kuzin@huawei.com \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=david@kernel.org \
    --cc=edumazet@google.com \
    --cc=harry.yoo@oracle.com \
    --cc=hramamurthy@google.com \
    --cc=ivgorbunov@me.com \
    --cc=joshwash@google.com \
    --cc=kirill@shutemov.name \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lorenzo.stoakes@oracle.com \
    --cc=mhocko@suse.com \
    --cc=muchun.song@linux.dev \
    --cc=pfalcato@suse.de \
    --cc=rppt@kernel.org \
    --cc=surenb@google.com \
    --cc=torvalds@linuxfoundation.org \
    --cc=vbabka@suse.cz \
    --cc=willy@infradead.org \
    --cc=yuzhao@google.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

all inboxes | Powered by JetHome®