Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mm: Document the folio refcount a little better
@ 2026-05-26 20:00 Matthew Wilcox (Oracle)
  2026-06-17 11:22 ` David Hildenbrand (Arm)
  0 siblings, 1 reply; 2+ messages in thread
From: Matthew Wilcox (Oracle) @ 2026-05-26 20:00 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Matthew Wilcox (Oracle), linux-mm

Expand the documentation of folio_ref_count() to talk about expected,
temporary and spurious refcounts as well as the concept of freezing.

Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
---
 include/linux/page_ref.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/include/linux/page_ref.h b/include/linux/page_ref.h
index 94d3f0e71c06..9f5c75d06f76 100644
--- a/include/linux/page_ref.h
+++ b/include/linux/page_ref.h
@@ -71,6 +71,12 @@ static inline int page_ref_count(const struct page *page)
  * folio_ref_count - The reference count on this folio.
  * @folio: The folio.
  *
+ * Folios contain a reference count.  When that reference count reaches
+ * zero, the folio is referred to as frozen.  At this point, it will
+ * usually be returned to the memory allocator, but some parts of the
+ * kernel freeze folios in order to perform unusual operations on them
+ * such as splitting or migration.
+ *
  * The refcount is usually incremented by calls to folio_get() and
  * decremented by calls to folio_put().  Some typical users of the
  * folio refcount:
@@ -82,6 +88,18 @@ static inline int page_ref_count(const struct page *page)
  * - Pipes
  * - Direct IO which references this page in the process address space
  *
+ * The reference count has three components: expected, temporary and
+ * spurious.  The expected reference count of a folio is that which
+ * we would logically expect it to be from just reading the code.
+ * Temporary refcounts are gained by threads which need a temporary
+ * reference to make sure the folio isn't reallocated while they use it.
+ * Spurious refcounts are gained by threads which, thanks to RCU walks
+ * of the page tables or file cache, find a stale pointer to a folio.
+ * These threads will drop the refcount after discoveering the pointer
+ * is stale, but it can surprise other users to see the spurious refcount
+ * on a freshly allocated folio (eg they may see a refcount of 2 instead
+ * of 1).
+ *
  * Return: The number of references to this folio.
  */
 static inline int folio_ref_count(const struct folio *folio)
-- 
2.47.3



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] mm: Document the folio refcount a little better
  2026-05-26 20:00 [PATCH] mm: Document the folio refcount a little better Matthew Wilcox (Oracle)
@ 2026-06-17 11:22 ` David Hildenbrand (Arm)
  0 siblings, 0 replies; 2+ messages in thread
From: David Hildenbrand (Arm) @ 2026-06-17 11:22 UTC (permalink / raw)
  To: Matthew Wilcox (Oracle), Andrew Morton; +Cc: linux-mm

On 5/26/26 22:00, Matthew Wilcox (Oracle) wrote:
> Expand the documentation of folio_ref_count() to talk about expected,
> temporary and spurious refcounts as well as the concept of freezing.
> 
> Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
> ---
>  include/linux/page_ref.h | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
> 
> diff --git a/include/linux/page_ref.h b/include/linux/page_ref.h
> index 94d3f0e71c06..9f5c75d06f76 100644
> --- a/include/linux/page_ref.h
> +++ b/include/linux/page_ref.h
> @@ -71,6 +71,12 @@ static inline int page_ref_count(const struct page *page)
>   * folio_ref_count - The reference count on this folio.
>   * @folio: The folio.
>   *
> + * Folios contain a reference count.  When that reference count reaches
> + * zero, the folio is referred to as frozen.  At this point, it will
> + * usually be returned to the memory allocator, but some parts of the
> + * kernel freeze folios in order to perform unusual operations on them
> + * such as splitting or migration.
> + *
>   * The refcount is usually incremented by calls to folio_get() and
>   * decremented by calls to folio_put().  Some typical users of the
>   * folio refcount:
> @@ -82,6 +88,18 @@ static inline int page_ref_count(const struct page *page)
>   * - Pipes
>   * - Direct IO which references this page in the process address space
>   *
> + * The reference count has three components: expected, temporary and
> + * spurious.  The expected reference count of a folio is that which
> + * we would logically expect it to be from just reading the code.
> + * Temporary refcounts are gained by threads which need a temporary
> + * reference to make sure the folio isn't reallocated while they use it.
> + * Spurious refcounts are gained by threads which, thanks to RCU walks

I think we often call them "Speculative references".

Not just RCU (GUP-fast doesn't even use RCU for page tables). We also have PFN
walkers that don't involve the pagecache or page tables at all. They don't find
stale pointers.

In essence, all these users use folio_try_get() and friends to grab a reference
speculatively, while the folio might have been freed concurrently, or the
pointer from where they might have obtained the folio could now be stale.

Maybe it's clearer to explain it from that angle.

-- 
Cheers,

David


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-06-17 11:22 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-26 20:00 [PATCH] mm: Document the folio refcount a little better Matthew Wilcox (Oracle)
2026-06-17 11:22 ` David Hildenbrand (Arm)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox