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