Re: [PATCH RFC 09/14] mm/page-flags: check page/folio->private instead of PG_private

"Zi Yan" <[email protected]>
Newsgroups org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-trace-kernel,org.kvack.linux-mm
Message-ID <[email protected]>
On Fri Jul 31, 2026 at 10:13 PM EDT, Zi Yan wrote:
> After the changes of the prior commits, page/folio->private != NULL is now
> equivalent to checking PG_private.
>
> Stop checking PG_private on pages and folios and use page/folio->private
> instead, except swapcache and hugetlb folios, because the former uses a
> field (swp_entry_t swap) overlapping with ->private and the latter sets its
> flags in ->private. Exclude swapcache and hugetlb when the code is meant to
> check PG_private only.
>
> folio_set/clear_private() and Set/ClearPagePrivate() become no-ops.
> PG_private is no longer checked at page free time.
>
> KPF_PRIVATE exposes PG_private to userspace. Change its code logic to check
> folio->private != NULL and exclude non-pagecache, swapcache, hugetlb, and
> anon folios. One minor semantic change, for orphaned pagecache folios
> (mapping == NULL) with fs-private data will no longer have KPF_PRIVATE.
>
> Assisted-by: Claude:claude-opus-4-8
> Assisted-by: Codex:gpt-5
> Signed-off-by: Zi Yan <[email protected]>
> To: Andrew Morton <[email protected]>
> To: David Hildenbrand <[email protected]>
> To: Steven Rostedt <[email protected]>
> To: Masami Hiramatsu <[email protected]>
> To: Lorenzo Stoakes <[email protected]>
> To: "Matthew Wilcox (Oracle)" <[email protected]>
> To: Jan Kara <[email protected]>
> To: Johannes Weiner <[email protected]>
> Cc: "Liam R. Howlett" <[email protected]>
> Cc: Vlastimil Babka <[email protected]>
> Cc: Mike Rapoport <[email protected]>
> Cc: Suren Baghdasaryan <[email protected]>
> Cc: Michal Hocko <[email protected]>
> Cc: Mathieu Desnoyers <[email protected]>
> Cc: Zi Yan <[email protected]>
> Cc: Baolin Wang <[email protected]>
> Cc: Nico Pache <[email protected]>
> Cc: Ryan Roberts <[email protected]>
> Cc: Dev Jain <[email protected]>
> Cc: Barry Song <[email protected]>
> Cc: Lance Yang <[email protected]>
> Cc: Usama Arif <[email protected]>
> Cc: Matthew Brost <[email protected]>
> Cc: Joshua Hahn <[email protected]>
> Cc: Rakie Kim <[email protected]>
> Cc: Byungchul Park <[email protected]>
> Cc: Gregory Price <[email protected]>
> Cc: Ying Huang <[email protected]>
> Cc: Alistair Popple <[email protected]>
> Cc: Qi Zheng <[email protected]>
> Cc: Shakeel Butt <[email protected]>
> Cc: Kairui Song <[email protected]>
> Cc: Axel Rasmussen <[email protected]>
> Cc: Yuanchu Xie <[email protected]>
> Cc: Wei Xu <[email protected]>
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> Cc: [email protected]
> ---
>  fs/proc/page.c                 |  6 +++++-
>  include/linux/mm.h             | 11 ++++++-----
>  include/linux/page-flags.h     | 26 +++++++++++++++++++++-----
>  include/trace/events/pagemap.h |  4 +++-
>  mm/huge_memory.c               |  4 +++-
>  mm/migrate.c                   |  3 ++-
>  mm/page-writeback.c            |  5 ++++-
>  mm/vmscan.c                    |  3 ++-
>  8 files changed, 46 insertions(+), 16 deletions(-)
>
> diff --git a/fs/proc/page.c b/fs/proc/page.c
> index 260772b20bd99..abfa6f7d890cc 100644
> --- a/fs/proc/page.c
> +++ b/fs/proc/page.c
> @@ -232,7 +232,11 @@ u64 stable_page_flags(const struct page *page)
>  
>  	u |= kpf_copy_bit(k, KPF_RESERVED,	PG_reserved);
>  	u |= kpf_copy_bit(k, KPF_OWNER_2,	PG_owner_2);
> -	u |= kpf_copy_bit(k, KPF_PRIVATE,	PG_private);
> +	/* preserve the original KPF_PRIVATE semantics by excluding non pagecache folios */
> +	if (folio->mapping && !folio_test_anon(folio) &&
> +	    (folio_get_private(folio) && !folio_test_swapcache(folio) &&
> +	     !folio_test_hugetlb(folio)))
> +		u |= BIT_ULL(KPF_PRIVATE);

Based on the discussion in THP cabal meeting, KPF_PRIVATE will be
removed in v2, since kernel page flags are not stable.

>  	u |= kpf_copy_bit(k, KPF_PRIVATE_2,	PG_private_2);
>  	u |= kpf_copy_bit(k, KPF_OWNER_PRIVATE,	PG_owner_priv_1);
>  	u |= kpf_copy_bit(k, KPF_ARCH,		PG_arch_1);
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 7fabe6c66b4b7..ebc035ac26ccc 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -2961,9 +2961,9 @@ static inline bool folio_maybe_mapped_shared(struct folio *folio)
>   * @folio: the folio
>   *
>   * Calculate the expected folio refcount, taking references from the pagecache,
> - * swapcache, PG_private and page table mappings into account. Useful in
> - * combination with folio_ref_count() to detect unexpected references (e.g.,
> - * GUP or other temporary references).
> + * swapcache, private data (folio->private != NULL) and page table mappings into
> + * account. Useful in combination with folio_ref_count() to detect unexpected
> + * references (e.g., GUP or other temporary references).
>   *
>   * Does currently not consider references from the LRU cache. If the folio
>   * was isolated from the LRU (which is the case during migration or split),
> @@ -3003,8 +3003,9 @@ static inline int folio_expected_ref_count(const struct folio *folio)
>  	if (!folio_test_anon(folio)) {
>  		/* One reference per page from the pagecache. */
>  		ref_count += !!folio->mapping << order;
> -		/* One reference from PG_private. */
> -		ref_count += folio_test_private(folio);
> +		/* One reference from filesystem private data. */
> +		ref_count += !!folio->private && !folio_test_hugetlb(folio) &&
> +			     !folio_test_swapcache(folio);
>  	}

Sashiko asked:

folio_expected_ref_count() can be called in lockless contexts, does
reading folio->private directly introduce a data race? And whether a
READ_ONCE() should be used for folio->private.


Answer:

Yes, we expect that and caller should recheck refcount after they hold
the folio lock. Use data_race() for folio->private reading. While at it,
add data_race() for folio->mapping too.




-- 
Best Regards,
Yan, Zi
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.