From: Zi Yan <ziy@nvidia.com>
To: David Hildenbrand <david@kernel.org>,
"Matthew Wilcox (Oracle)" <willy@infradead.org>,
Andrew Morton <akpm@linux-foundation.org>,
Muchun Song <muchun.song@linux.dev>,
Lorenzo Stoakes <ljs@kernel.org>,
"Liam R. Howlett" <liam@infradead.org>,
Vlastimil Babka <vbabka@kernel.org>,
Mike Rapoport <rppt@kernel.org>,
Suren Baghdasaryan <surenb@google.com>,
Michal Hocko <mhocko@suse.com>,
Baolin Wang <baolin.wang@linux.alibaba.com>,
Nico Pache <nico.pache@linux.dev>,
Ryan Roberts <ryan.roberts@arm.com>, Dev Jain <dev.jain@arm.com>,
Barry Song <baohua@kernel.org>,
Lance Yang <lance.yang@linux.dev>,
Usama Arif <usama.arif@linux.dev>,
Gregory Price <gourry@gourry.net>,
Ying Huang <ying.huang@linux.alibaba.com>,
Alistair Popple <apopple@nvidia.com>,
Johannes Weiner <hannes@cmpxchg.org>,
Qi Zheng <qi.zheng@linux.dev>,
Shakeel Butt <shakeel.butt@linux.dev>,
Kairui Song <kasong@tencent.com>
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org,
Zi Yan <ziy@nvidia.com>, Steven Rostedt <rostedt@goodmis.org>,
Masami Hiramatsu <mhiramat@kernel.org>, Jan Kara <jack@suse.cz>,
Mathieu Desnoyers <mathieu.desnoyers@efficios.com>,
Matthew Brost <matthew.brost@intel.com>,
Joshua Hahn <joshua.hahnjy@gmail.com>,
Rakie Kim <rakie.kim@sk.com>, Byungchul Park <byungchul@sk.com>,
Axel Rasmussen <axelrasmussen@google.com>,
Yuanchu Xie <yuanchu@google.com>, Wei Xu <weixugc@google.com>,
linux-fsdevel@vger.kernel.org,
linux-trace-kernel@vger.kernel.org
Subject: [PATCH RFC 09/14] mm/page-flags: check page/folio->private instead of PG_private
Date: Fri, 31 Jul 2026 22:13:32 -0400 [thread overview]
Message-ID: <20260731-remove-pg_private-v1-9-142c97ba3562@nvidia.com> (raw)
In-Reply-To: <20260731-remove-pg_private-v1-0-142c97ba3562@nvidia.com>
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 <ziy@nvidia.com>
To: Andrew Morton <akpm@linux-foundation.org>
To: David Hildenbrand <david@kernel.org>
To: Steven Rostedt <rostedt@goodmis.org>
To: Masami Hiramatsu <mhiramat@kernel.org>
To: Lorenzo Stoakes <ljs@kernel.org>
To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
To: Jan Kara <jack@suse.cz>
To: Johannes Weiner <hannes@cmpxchg.org>
Cc: "Liam R. Howlett" <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Nico Pache <nico.pache@linux.dev>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Usama Arif <usama.arif@linux.dev>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Rakie Kim <rakie.kim@sk.com>
Cc: Byungchul Park <byungchul@sk.com>
Cc: Gregory Price <gourry@gourry.net>
Cc: Ying Huang <ying.huang@linux.alibaba.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Qi Zheng <qi.zheng@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Kairui Song <kasong@tencent.com>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: Wei Xu <weixugc@google.com>
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-trace-kernel@vger.kernel.org
---
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);
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);
}
/* One reference per page table mapping. */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 7a863572adce7..8efc61f967302 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -578,7 +578,23 @@ FOLIO_FLAG(swapbacked, FOLIO_HEAD_PAGE)
* for its own purposes.
* - PG_private and PG_private_2 cause release_folio() and co to be invoked
*/
-PAGEFLAG(Private, private, PF_ANY)
+
+static __always_inline bool folio_test_private(const struct folio *folio)
+{
+ return folio->private;
+}
+
+static __always_inline int PagePrivate(const struct page *page)
+{
+ return !!page_private(page);
+}
+
+/* no-ops during transition */
+static __always_inline void folio_set_private(struct folio *folio) { }
+static __always_inline void folio_clear_private(struct folio *folio) { }
+static __always_inline void SetPagePrivate(struct page *page) { }
+static __always_inline void ClearPagePrivate(struct page *page) { }
+
FOLIO_FLAG(private_2, FOLIO_HEAD_PAGE)
/* owner_2 can be set on tail pages for anon memory */
@@ -1170,7 +1186,7 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
*/
#define PAGE_FLAGS_CHECK_AT_FREE \
(1UL << PG_lru | 1UL << PG_locked | \
- 1UL << PG_private | 1UL << PG_private_2 | \
+ 1UL << PG_private_2 | \
1UL << PG_writeback | 1UL << PG_reserved | \
1UL << PG_active | \
1UL << PG_unevictable | __PG_MLOCKED | LRU_GEN_MASK)
@@ -1194,8 +1210,6 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
(0xffUL /* order */ | 1UL << PG_has_hwpoisoned | \
1UL << PG_large_rmappable | 1UL << PG_partially_mapped)
-#define PAGE_FLAGS_PRIVATE \
- (1UL << PG_private | 1UL << PG_private_2)
/**
* folio_has_private - Determine if folio has private stuff
* @folio: The folio to be checked
@@ -1205,7 +1219,9 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
*/
static inline int folio_has_private(const struct folio *folio)
{
- return !!(folio->flags.f & PAGE_FLAGS_PRIVATE);
+ return (!!folio->private && !folio_test_swapcache(folio) &&
+ !folio_test_hugetlb(folio)) ||
+ folio_test_private_2(folio);
}
#undef PF_ANY
diff --git a/include/trace/events/pagemap.h b/include/trace/events/pagemap.h
index 36c3a90f0acca..fb9abec40ec79 100644
--- a/include/trace/events/pagemap.h
+++ b/include/trace/events/pagemap.h
@@ -22,7 +22,9 @@
(folio_test_swapcache(folio) ? PAGEMAP_SWAPCACHE : 0) | \
(folio_test_swapbacked(folio) ? PAGEMAP_SWAPBACKED : 0) | \
(folio_test_mappedtodisk(folio) ? PAGEMAP_MAPPEDDISK : 0) | \
- (folio_test_private(folio) ? PAGEMAP_BUFFERS : 0) \
+ (folio_test_private(folio) && \
+ !folio_test_swapcache(folio) && \
+ !folio_test_hugetlb(folio) ? PAGEMAP_BUFFERS : 0) \
)
TRACE_EVENT(mm_lru_insertion,
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 21c92ee48e469..d21a9b8f40d15 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -4799,7 +4799,9 @@ static int split_huge_pages_pid(int pid, unsigned long vaddr_start,
* will try to drop it before split and then check if the folio
* can be split or not. So skip the check here.
*/
- if (!folio_test_private(folio) &&
+ if (!(folio_test_private(folio) &&
+ !folio_test_swapcache(folio) &&
+ !folio_test_hugetlb(folio)) &&
folio_expected_ref_count(folio) != folio_ref_count(folio))
goto next;
diff --git a/mm/migrate.c b/mm/migrate.c
index b937cbd764808..ad5daef8721cf 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1330,7 +1330,8 @@ static int migrate_folio_unmap(new_folio_t get_new_folio,
* free the metadata, so the page can be freed.
*/
if (!src->mapping) {
- if (folio_test_private(src)) {
+ if (folio_test_private(src) && !folio_test_swapcache(src) &&
+ !folio_test_hugetlb(src)) {
try_to_free_buffers(src);
goto out;
}
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 47495be68598f..b44468383f900 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2706,7 +2706,10 @@ bool filemap_dirty_folio(struct address_space *mapping, struct folio *folio)
if (folio_test_set_dirty(folio))
return false;
- __folio_mark_dirty(folio, mapping, !folio_test_private(folio));
+ __folio_mark_dirty(folio, mapping,
+ !(folio_test_private(folio) &&
+ !folio_test_swapcache(folio) &&
+ !folio_test_hugetlb(folio)));
if (mapping->host) {
/* !PageAnon && !swapper_space */
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 17d2b793cbfc4..ab059a2c6ea35 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -954,7 +954,8 @@ static void folio_check_dirty_writeback(struct folio *folio,
*writeback = folio_test_writeback(folio);
/* Verify dirty/writeback state if the filesystem supports it */
- if (!folio_test_private(folio))
+ if (!(folio_test_private(folio) && !folio_test_swapcache(folio) &&
+ !folio_test_hugetlb(folio)))
return;
mapping = folio_mapping(folio);
--
2.53.0
next prev parent reply other threads:[~2026-08-01 2:17 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-01 2:13 [PATCH RFC 00/14] Remove PG_private by using page/folio->private checks instead Zi Yan
2026-08-01 2:13 ` [f2fs-dev] " Zi Yan via Linux-f2fs-devel
2026-08-01 2:13 ` Zi Yan
2026-08-01 2:13 ` [PATCH RFC 01/14] mm/zsmalloc: replace PG_private with pointer comparison Zi Yan
2026-08-01 14:12 ` Usama Arif
2026-08-01 23:49 ` Zi Yan
2026-08-02 12:05 ` Usama Arif
2026-08-02 18:38 ` Zi Yan
2026-08-03 15:04 ` Johannes Weiner
2026-08-03 15:34 ` Zi Yan
2026-08-03 16:53 ` Johannes Weiner
2026-08-03 21:05 ` Zi Yan
2026-08-04 0:51 ` Johannes Weiner
2026-08-04 6:37 ` Sergey Senozhatsky
2026-08-04 15:28 ` Zi Yan
2026-08-01 2:13 ` [PATCH RFC 02/14] perf/ring_buffer: stop using PG_private as AUX page high-order marker Zi Yan
2026-08-01 14:32 ` Usama Arif
2026-08-02 1:20 ` Zi Yan
2026-08-01 2:13 ` [PATCH RFC 03/14] xen/grant-table: stop setting PG_private on pages for grant mapping Zi Yan
2026-08-01 14:42 ` Usama Arif
2026-08-02 1:24 ` Zi Yan
2026-08-01 2:13 ` [PATCH RFC 04/14] fs/crypto: stop setting PG_private on bounce page Zi Yan
2026-08-01 14:52 ` Usama Arif
2026-08-02 1:29 ` Zi Yan
2026-08-03 18:40 ` Eric Biggers
2026-08-01 2:13 ` [PATCH RFC 05/14] mm/hugetlb: use direct assignment instead of folio_change_private() Zi Yan
2026-08-02 12:16 ` Usama Arif
2026-08-02 18:38 ` Zi Yan
2026-08-01 2:13 ` [PATCH RFC 06/14] fs/f2fs: stop using PG_private Zi Yan
2026-08-01 2:13 ` [f2fs-dev] " Zi Yan via Linux-f2fs-devel
2026-08-03 11:17 ` Chao Yu via Linux-f2fs-devel
2026-08-03 11:17 ` Chao Yu
2026-08-03 15:48 ` [f2fs-dev] " Usama Arif
2026-08-03 15:48 ` Usama Arif
2026-08-01 2:13 ` [PATCH RFC 07/14] fs/erofs: mm/pagemap: add readahead_folio_reverse() to avoid folio->private Zi Yan
2026-08-03 9:54 ` Jan Kara
2026-08-03 16:56 ` Zi Yan
2026-08-04 9:32 ` Jan Kara
2026-08-04 15:54 ` Zi Yan
2026-08-04 17:04 ` Jan Kara
2026-08-04 17:09 ` Zi Yan
2026-08-05 2:37 ` Zi Yan
2026-08-05 9:25 ` Jan Kara
2026-08-05 11:42 ` Zi Yan
2026-08-05 13:51 ` Zi Yan
2026-08-05 16:10 ` Jan Kara
2026-08-03 23:55 ` Gao Xiang
2026-08-01 2:13 ` [PATCH RFC 08/14] fs/erofs: use folio_attach/detach_private() instead of direct assignment Zi Yan
2026-08-03 23:40 ` Gao Xiang
2026-08-05 2:41 ` Zi Yan
2026-08-05 4:17 ` Gao Xiang
2026-08-01 2:13 ` Zi Yan [this message]
2026-08-01 2:13 ` [PATCH RFC 10/14] mm/page-flags: introduce folio_test_fs_private() Zi Yan
2026-08-01 2:13 ` [PATCH RFC 11/14] treewide: remove folio_set/clear_private() Zi Yan
2026-08-01 2:13 ` [PATCH RFC 12/14] treewide: replace PagePrivate() with page_private() Zi Yan
2026-08-01 2:13 ` [PATCH RFC 13/14] treewide: adjust comments on PagePrivate and PG_private Zi Yan
2026-08-01 2:13 ` Zi Yan
2026-08-01 2:13 ` [PATCH RFC 14/14] mm/page-flags: remove PG_private Zi Yan
2026-08-03 9:07 ` [PATCH RFC 00/14] Remove PG_private by using page/folio->private checks instead Jürgen Groß
2026-08-03 9:07 ` Jürgen Groß
2026-08-03 18:13 ` Zi Yan
2026-08-03 18:13 ` [f2fs-dev] " Zi Yan via Linux-f2fs-devel
2026-08-03 18:13 ` Zi Yan
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=20260731-remove-pg_private-v1-9-142c97ba3562@nvidia.com \
--to=ziy@nvidia.com \
--cc=akpm@linux-foundation.org \
--cc=apopple@nvidia.com \
--cc=axelrasmussen@google.com \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=byungchul@sk.com \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=gourry@gourry.net \
--cc=hannes@cmpxchg.org \
--cc=jack@suse.cz \
--cc=joshua.hahnjy@gmail.com \
--cc=kasong@tencent.com \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-trace-kernel@vger.kernel.org \
--cc=ljs@kernel.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=matthew.brost@intel.com \
--cc=mhiramat@kernel.org \
--cc=mhocko@suse.com \
--cc=muchun.song@linux.dev \
--cc=nico.pache@linux.dev \
--cc=qi.zheng@linux.dev \
--cc=rakie.kim@sk.com \
--cc=rostedt@goodmis.org \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=shakeel.butt@linux.dev \
--cc=surenb@google.com \
--cc=usama.arif@linux.dev \
--cc=vbabka@kernel.org \
--cc=weixugc@google.com \
--cc=willy@infradead.org \
--cc=ying.huang@linux.alibaba.com \
--cc=yuanchu@google.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.