All of lore.kernel.org
 help / color / mirror / Atom feed
From: "David Hildenbrand (Arm)" <david@kernel.org>
To: Ilya Gladyshev <ilya.gladyshev@linux.dev>, 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, 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
Subject: Re: [PATCH v6 3/3] mm: implement page refcount locking via dedicated bit
Date: Thu, 24 Sep 2026 20:51:50 +0200	[thread overview]
Message-ID: <570cf649-a8bf-4073-be71-207fbb2bef40@kernel.org> (raw)
In-Reply-To: <56e036665dbeb0a8f51d697220d5ed84f210994c@linux.dev>

On 9/23/26 19:34, Ilya Gladyshev wrote:
> 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...

There needs to be a common page freeing function that dipatches stuff.

folio_put() is not the best future-proof thing, because not all pages will be
folios sooninsh.

-- 
Cheers,

David


  reply	other threads:[~2026-09-24 18:52 UTC|newest]

Thread overview: 20+ 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
2026-09-24 18:51       ` David Hildenbrand (Arm) [this message]
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 19:00               ` Linus Torvalds
2026-09-25 22:46                 ` Ilya Gladyshev
2026-09-25  7:15             ` David Hildenbrand (Arm)
2026-09-25 19:38   ` Matthew Wilcox
2026-09-25 23:13     ` Ilya Gladyshev
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=570cf649-a8bf-4073-be71-207fbb2bef40@kernel.org \
    --to=david@kernel.org \
    --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=edumazet@google.com \
    --cc=harry.yoo@oracle.com \
    --cc=hramamurthy@google.com \
    --cc=ilya.gladyshev@linux.dev \
    --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 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.