* [PATCH v5 00/17] Remove PG_private by using page/folio->private checks instead
@ 2026-09-21 2:27 Zi Yan
2026-09-21 2:27 ` [PATCH v5 02/17] perf/ring_buffer: stop using PG_private as AUX page high-order marker Zi Yan
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Zi Yan @ 2026-09-21 2:27 UTC (permalink / raw)
To: David Hildenbrand, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Zi Yan, Minchan Kim, Sergey Senozhatsky,
Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Thomas Gleixner, Borislav Petkov, Dave Hansen, x86,
Mark Rutland, Alexander Shishkin, Jiri Olsa, Ian Rogers,
Adrian Hunter, James Clark, H. Peter Anvin, linux-perf-users,
Juergen Gross, Stefano Stabellini, Oleksandr Tyshchenko,
xen-devel, Eric Biggers, Theodore Y. Ts'o, Jaegeuk Kim,
linux-fscrypt, Oscar Salvador, Chao Yu, linux-f2fs-devel,
Tal Zussman, Gao Xiang, Jan Kara, Yue Hu, Jeffle Xu,
Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs,
linux-fsdevel, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Matthew Brost, Joshua Hahn, Rakie Kim,
Byungchul Park, Axel Rasmussen, Yuanchu Xie, Wei Xu,
linux-trace-kernel, Trond Myklebust, Anna Schumaker, linux-nfs,
Ilya Dryomov, Alex Markuze, Viacheslav Dubeyko, ceph-devel,
Richard Weinberger, Zhihao Cheng, linux-mtd, Baoquan He,
Pasha Tatashin, Pratyush Yadav, Jonathan Corbet, Dave Young,
Shuah Khan, kexec, linux-doc
Hi all,
This patchset removes PG_private to make space for upcoming PG_folio for
identifying pages from a folio (more details in Note below). Instead of
checking PG_private, all code is changed to check page/folio->private !=
NULL instead.
MM people are cc'd on all patches and subsystem people are cc'd on the
cover letter and corresponding patches.
This patchset is on top of commit ef0ea92854987 ("mm: zswap: return -ENOENT
when the swap device is gone") from mm-new, which is the same base as V4 of
this patchset and no conflict is found during the rebase. I also tried to
cherry pick the remaining patches from mm-everything on top of this
patchset and find no conflict.
Patch 10 and Patch 13 are the only two patches without any Ack or Rb tag.
Overview
===
Most code uses folio_attach/detach/change_private() functions, so folio
refcount is increased and decreased when folio->private is set and reset,
respectively. There is no need to change them.
Changes are needed for exceptional users:
1. zsmalloc uses PG_private to indicate first component zpdesc page and
page->private is used to store zspage in zpdesc. To remove PG_private,
is_first_zpdesc() is replaced by pointer comparison.
2. kernel/events/ring_buffer.c stores page order in page->private.
Replacing PG_private with page->private != NULL works.
3. drivers/xen/grant-table.c stores xen_page_foreign in page->private,
where on 32-bit, a pointer to xen_page_foreign is stored; on 64-bit,
page->private is used as xen_page_foreign. PG_private check is replaced
by page->private != NULL on 32-bit for xen_page_foreign deallocation.
On 64-bit, page->private is cleared unconditionally since {domid=0,
gref=0} (xen_page_foreign can be 0) is valid.
4. fs/crypto/crypto.c stores a folio pointer in page->private, PG_private
checks are replaced by page->private != NULL.
5. fs/erofs has two different uses:
5a. folio->private is used to form a reversed list of
the outputs of readahead_folio(). readahead_folio_last() is added to
output folios in reversed order, so that ->private is no longer needed.
5b. folio->private is used as an in-flight I/O counter. Convert the
code to use folio_attach/detach/get_private() and add bias==1 to the
counter to avoid folio->private being zero.
6. fs/nfs/write.c: folio refcount maintenance is in a bigger scope than
folio->private. So folio_attach/detach/get_private() is not used.
Nothing to change.
7. fs/f2fs uses attach_page_private() to first reset folio->private then
immediately sets PAGE_PRIVATE_NOT_POINTER bit on it. Change it to use
attach_page_private() to set PAGE_PRIVATE_NOT_POINTER bit directly to
avoid folio->private == NULL gap inside set_page_private_##name().
8. hugetlb uses folio_change_private(folio, NULL) without folio refcount
maintenance. Change it to folio->private = NULL.
After the above changes, PG_private ops are converted to
page/folio->private ops.
folio_has_attached_private() is added to check filesystem-only private data
by excluding swapcache and hugetlb folios, because swapcache folios overlap
swp_entry_t swap with ->private and hugetlb sets its own flags in
->private.
Note
===
1. KPF_PRIVATE is removed after PG_private is removed.
2. Documentation/mm/hugetlbfs_reserv.rst is outdated, so I did not remove
PG_private related text. It should be rewritten.
3. PG_folio is planned to be set on every page from a folio in
page_rmappable_folio(), so folios with any order (currently
PG_large_rmappable is used to identify >0 order folios, but not order-0
folios) can be identified. Then vm_insert_*() can correctly reject all
folios and rmap code will only see folios. Eventually, page_folio()
will return NULL for non-folio pages by checking PG_folio, but before
that all existing users that treat compound pages as folios will need
to be converted.
Tests
===
1. allmodconfig build passed.
2. zsmalloc is tested using ext4 on a 1GB lz4 zram:
2a. zram load + zsmalloc compaction;
2b. concurrent zspage migration via memory compaction;
2c. confirmed that multi-page zspages actually formed.
Details: https://github.com/x-y-z/linux-dev/blob/b4/remove-pg_private/test_zsmalloc.md
3. erofs is tested on images created with -C4096 and lz4hc, lzma,
deflate, and zstd algorithms:
3a. cold read of all files, verify checksums match source;
3b. readahead + reclaim/migration race.
Details: https://github.com/x-y-z/linux-dev/blob/b4/remove-pg_private/test_erofs.md
4. fscrypt is tested on software-encrypted ext4 with writes to exercise
bounce pages.
Details: https://github.com/x-y-z/linux-dev/blob/b4/remove-pg_private/test_fscrypt.md
5. f2fs is tested on an image with inline_data,compress_algorithm=lz4:
5a. INLINE_INODE — lots of tiny files;
5b. REF_RESOURCE + general writeback — buffered write churn with fsync;
5c. ONGOING_MIGRATION — force GC / page migration;
5d. ATOMIC_WRITE — atomic-write ioctl path.
Details: https://github.com/x-y-z/linux-dev/blob/b4/remove-pg_private/test_f2fs.md
(I did not run xfstests)
6. MM selftests passed.
LLM use
===
Claude was used to form a concrete plan on what code needs to be changed
and how to change them. The plan was reviewed by Codex until no issue was
spotted.
Plan is at: https://github.com/x-y-z/linux-dev/blob/b4/remove-pg_private/plan.md
I then followed the plan to make code changes. I did bounce ideas with
Claude how to change fs/erofs, since I did not like the original idea.
After each change, I asked Claude to review my code and git commit message.
I also asked Claude to give me test plans (see above).
At last, Codex was used to review all patches.
Comments and suggestions are welcome. Thanks.
Assisted-by: LLM
Signed-off-by: Zi Yan <ziy@nvidia.com>
---
Changes in v5:
1. replaced md patches (patch 13 and 14 in v4) with Matthew Wilcox's
version (see Matthew's replies to v4).
2. used data_race() inside folio_test_private() and PagePrivate(), so that
the new versions can be used without KCSAN warnings while not holding
folio lock like before.
3. moved folio_has_attached_private() implementation detail comment next to
the code.
- Link to v4: https://patch.msgid.link/20260913-remove-pg_private-v4-0-848550f7574e@nvidia.com
Changes in v4:
1. dropped set_page_private(0) in balloon_retrieve(), since page->private
is cleared at that point.
2. simplified the comment in add_hugetlb_folio().
3. additional cleanup for f2fs to remove fio->page uses and convert
PAGE_PRIVATE_* flags and helper to folio-only.
4. added a comment for __readahead_advance().
5. added core-mm split/migration interaction information on newly added
folio_attach/detach_private() for erofs.
6. renamed folio_test_fs_private() to folio_has_attached_private() and
merged the commit introducing folio_test_fs_private() into its prior
commit.
7. adjusted the patch subject: "treewide: remove folio_set/clear_private()
*usage*"
8. split "treewide: replace PagePrivate() with page_private()" into three.
9. moved some comments in "treewide: remove PagePrivate() and PG_private
from comments and docs" to prior patches along with code changes.
10. used PG_folio instead of __PG_folio to avoid additional
code change in __def_pageflag_names().
- Link to v3: https://patch.msgid.link/20260907-remove-pg_private-v3-0-6ae22f9d9272@nvidia.com
Changes in v3:
1. changed folio_test_fs_private() to check PG_swapbacked instead of
PG_swapcache for excluding swapcache folios. Because folio->private and
PG_swapcache are not set as a whole, making folio_test_fs_private() give
false positive, whereas PG_swapbacked is always set for swapcache
folios.
2. added __DEF_PAGEFLAG_NAME() to show __PG_folio instead of open code.
3. f2fs change is picked up at
https://git.kernel.org/jaegeuk/f2fs/c/5ad9409a9533, mm-new currently
does not have it, so the patch is sent for MM testing purpose.
- Link to v2: https://patch.msgid.link/20260831-remove-pg_private-v2-0-3668159cd9e8@nvidia.com
Changes in v2:
1. removed is_first_zpdesc() in patch 1 and open coded the checks.
2. fixed wording in patch 2's commit message and clarified page_private()
also works when ring buffer's AUX page order is 0.
3. removed the empty loop in 64-bit gnttab_pages_set_private().
4. clarified folio->private will be reset to NULL by
fscrypt_free_bounce_page() in the commit message.
5. clarified why hugetlb needs to restore hugetlb_vmemmap_optimized.
6. renamed readahead_folio_reverse() readahead_folio_last() and
reimplemented readahead_folio_last() by adding a new readahead_control
private member, _forward, and a new helper __readahead_advance().
7. added a bias, 1, to erofs I/O counter, so that folio->private stays non
NULL between folio_attach_private() and folio_detach_private().
8. converted more call sites to use folio_test_fs_private().
- Link to v1: https://lore.kernel.org/r/20260731-remove-pg_private-v1-0-142c97ba3562@nvidia.com
---
Matthew Wilcox (Oracle) (3):
md: Use folio_alloc_buffers()
md: Use folio APIs in free_page()
md: Remove the last use of page_buffers()
Zi Yan (14):
mm/zsmalloc: replace PG_private with pointer comparison
perf/ring_buffer: stop using PG_private as AUX page high-order marker
xen/grant-table: stop setting PG_private on pages for grant mapping
fscrypt: stop setting PG_private on bounce page
mm/hugetlb: use direct assignment instead of folio_change_private()
f2fs: stop using PG_private
f2fs: convert the ->private flag helpers to folio-only
erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private
erofs: use folio_attach/detach_private() instead of direct assignment
mm/page-flags: check page/folio->private instead of PG_private
treewide: remove folio_set/clear_private() usage
ceph: replace PagePrivate() with page_private()
treewide: remove PagePrivate() and PG_private from comments and docs
mm/page-flags: remove PG_private
Documentation/admin-guide/kdump/vmcoreinfo.rst | 2 +-
Documentation/filesystems/vfs.rst | 6 +-
arch/x86/events/intel/bts.c | 3 -
arch/x86/events/intel/pt.c | 6 +-
drivers/md/md-bitmap.c | 18 +++--
drivers/xen/grant-table.c | 11 ++-
fs/buffer.c | 8 ---
fs/ceph/addr.c | 8 +--
fs/crypto/crypto.c | 2 -
fs/erofs/data.c | 16 +++--
fs/erofs/zdata.c | 13 +---
fs/f2fs/compress.c | 35 +++++----
fs/f2fs/data.c | 2 +-
fs/f2fs/f2fs.h | 99 ++++++++++----------------
fs/f2fs/segment.c | 2 +-
fs/nfs/file.c | 4 +-
fs/nfs/write.c | 2 -
fs/proc/page.c | 1 -
fs/ubifs/file.c | 8 +--
include/linux/buffer_head.h | 8 +--
include/linux/kernel-page-flags.h | 1 -
include/linux/mm.h | 34 +++++----
include/linux/mm_types.h | 4 +-
include/linux/page-flags.h | 51 ++++++++++---
include/linux/pagemap.h | 64 ++++++++++++++---
include/trace/events/mmflags.h | 2 +-
include/trace/events/pagemap.h | 2 +-
kernel/events/ring_buffer.c | 7 +-
kernel/vmcore_info.c | 1 -
mm/huge_memory.c | 2 +-
mm/hugetlb.c | 7 +-
mm/migrate.c | 3 +-
mm/page-writeback.c | 2 +-
mm/vmscan.c | 2 +-
mm/zpdesc.h | 2 +-
mm/zsmalloc.c | 24 ++-----
tools/mm/page-types.c | 2 -
37 files changed, 238 insertions(+), 226 deletions(-)
---
base-commit: ef0ea92854987c1e61cd72e100c8b61b485955d8
change-id: 20260728-remove-pg_private-cfe926c7f83c
Best regards,
--
Yan, Zi
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 02/17] perf/ring_buffer: stop using PG_private as AUX page high-order marker
2026-09-21 2:27 [PATCH v5 00/17] Remove PG_private by using page/folio->private checks instead Zi Yan
@ 2026-09-21 2:27 ` Zi Yan
2026-09-21 2:38 ` sashiko-bot
2026-09-21 6:19 ` Lance Yang
2026-09-21 4:08 ` [PATCH v5 00/17] Remove PG_private by using page/folio->private checks instead Andrew Morton
2026-09-22 4:16 ` Nanzhe Zhao
2 siblings, 2 replies; 7+ messages in thread
From: Zi Yan @ 2026-09-21 2:27 UTC (permalink / raw)
To: David Hildenbrand, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song
Cc: linux-mm, linux-kernel, Zi Yan, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Namhyung Kim, Thomas Gleixner,
Borislav Petkov, Dave Hansen, x86, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, H. Peter Anvin, linux-perf-users
A high-order AUX page sets PG_private on its first page and stores the
order in first_page->private. Stop using PG_private and check
first_page->private for AUX page order only in the ring buffer and its
users. This is fine because page->private is 0 for order-0 AUX pages,
matching the page order.
It prepares for a future commit that remove PG_private.
No functional change intended.
Assisted-by: LLM
To: Peter Zijlstra <peterz@infradead.org>
To: Ingo Molnar <mingo@redhat.com>
To: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Namhyung Kim <namhyung@kernel.org>
To: Thomas Gleixner <tglx@kernel.org>
To: Borislav Petkov <bp@alien8.de>
To: Dave Hansen <dave.hansen@linux.intel.com>
To: x86@kernel.org
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: James Clark <james.clark@linaro.org>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: linux-perf-users@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Acked-by: Usama Arif <usama.arif@linux.dev>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Zi Yan <ziy@nvidia.com>
---
arch/x86/events/intel/bts.c | 3 ---
arch/x86/events/intel/pt.c | 6 ++----
kernel/events/ring_buffer.c | 7 +++----
3 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/arch/x86/events/intel/bts.c b/arch/x86/events/intel/bts.c
index cbac54cb3a9ec..5849392cf26d5 100644
--- a/arch/x86/events/intel/bts.c
+++ b/arch/x86/events/intel/bts.c
@@ -66,9 +66,6 @@ static struct pmu bts_pmu;
static int buf_nr_pages(struct page *page)
{
- if (!PagePrivate(page))
- return 1;
-
return 1 << page_private(page);
}
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c
index 5754cd4055628..49349afee6119 100644
--- a/arch/x86/events/intel/pt.c
+++ b/arch/x86/events/intel/pt.c
@@ -781,8 +781,7 @@ static int topa_insert_pages(struct pt_buffer *buf, int cpu, gfp_t gfp)
struct page *p;
p = virt_to_page(buf->data_pages[buf->nr_pages]);
- if (PagePrivate(p))
- order = page_private(p);
+ order = page_private(p);
if (topa_table_full(topa)) {
topa = topa_alloc(cpu, gfp);
@@ -1296,8 +1295,7 @@ static int pt_buffer_try_single(struct pt_buffer *buf, int nr_pages)
if (!intel_pt_validate_hw_cap(PT_CAP_single_range_output))
goto out;
- if (PagePrivate(p))
- order = page_private(p);
+ order = page_private(p);
if (1 << order != nr_pages)
goto out;
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 9fe92161715e0..061b5cb222266 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -630,11 +630,10 @@ static struct page *rb_alloc_aux_page(int node, int order)
/*
* Communicate the allocation size to the driver:
* if we managed to secure a high-order allocation,
- * set its first page's private to this order;
- * !PagePrivate(page) means it's just a normal page.
+ * set its first page's private to this order, otherwise page's
+ * private remains zero.
*/
split_page(page, order);
- SetPagePrivate(page);
set_page_private(page, order);
}
@@ -645,7 +644,7 @@ static void rb_free_aux_page(struct perf_buffer *rb, int idx)
{
struct page *page = virt_to_page(rb->aux_pages[idx]);
- ClearPagePrivate(page);
+ set_page_private(page, 0);
__free_page(page);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v5 02/17] perf/ring_buffer: stop using PG_private as AUX page high-order marker
2026-09-21 2:27 ` [PATCH v5 02/17] perf/ring_buffer: stop using PG_private as AUX page high-order marker Zi Yan
@ 2026-09-21 2:38 ` sashiko-bot
2026-09-21 6:19 ` Lance Yang
1 sibling, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-09-21 2:38 UTC (permalink / raw)
To: Zi Yan; +Cc: linux-perf-users
> A high-order AUX page sets PG_private on its first page and stores the
> order in first_page->private. Stop using PG_private and check
> first_page->private for AUX page order only in the ring buffer and its
> users. This is fine because page->private is 0 for order-0 AUX pages,
> matching the page order.
>
> It prepares for a future commit that remove PG_private.
>
> No functional change intended.
>
> Assisted-by: LLM
> To: Peter Zijlstra <peterz@infradead.org>
> To: Ingo Molnar <mingo@redhat.com>
> To: Arnaldo Carvalho de Melo <acme@kernel.org>
> To: Namhyung Kim <namhyung@kernel.org>
> [ ... ]
> Cc: linux-perf-users@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Acked-by: Usama Arif <usama.arif@linux.dev>
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
> Signed-off-by: Zi Yan <ziy@nvidia.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260920-remove-pg_private-v5-0-bb68b6a21869@nvidia.com?part=2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 00/17] Remove PG_private by using page/folio->private checks instead
2026-09-21 2:27 [PATCH v5 00/17] Remove PG_private by using page/folio->private checks instead Zi Yan
2026-09-21 2:27 ` [PATCH v5 02/17] perf/ring_buffer: stop using PG_private as AUX page high-order marker Zi Yan
@ 2026-09-21 4:08 ` Andrew Morton
2026-09-22 4:16 ` Nanzhe Zhao
2 siblings, 0 replies; 7+ messages in thread
From: Andrew Morton @ 2026-09-21 4:08 UTC (permalink / raw)
To: Zi Yan
Cc: David Hildenbrand, Matthew Wilcox (Oracle), Muchun Song,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Baolin Wang, Nico Pache,
Ryan Roberts, Dev Jain, Barry Song, Lance Yang, Usama Arif,
Gregory Price, Ying Huang, Alistair Popple, Johannes Weiner,
Qi Zheng, Shakeel Butt, Kairui Song, linux-mm, linux-kernel,
Minchan Kim, Sergey Senozhatsky, Peter Zijlstra, Ingo Molnar,
Arnaldo Carvalho de Melo, Namhyung Kim, Thomas Gleixner,
Borislav Petkov, Dave Hansen, x86, Mark Rutland,
Alexander Shishkin, Jiri Olsa, Ian Rogers, Adrian Hunter,
James Clark, H. Peter Anvin, linux-perf-users, Juergen Gross,
Stefano Stabellini, Oleksandr Tyshchenko, xen-devel, Eric Biggers,
Theodore Y. Ts'o, Jaegeuk Kim, linux-fscrypt, Oscar Salvador,
Chao Yu, linux-f2fs-devel, Tal Zussman, Gao Xiang, Jan Kara,
Yue Hu, Jeffle Xu, Sandeep Dhavale, Hongbo Li, Chunhai Guo,
linux-erofs, linux-fsdevel, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Matthew Brost, Joshua Hahn, Rakie Kim,
Byungchul Park, Axel Rasmussen, Yuanchu Xie, Wei Xu,
linux-trace-kernel, Trond Myklebust, Anna Schumaker, linux-nfs,
Ilya Dryomov, Alex Markuze, Viacheslav Dubeyko, ceph-devel,
Richard Weinberger, Zhihao Cheng, linux-mtd, Baoquan He,
Pasha Tatashin, Pratyush Yadav, Jonathan Corbet, Dave Young,
Shuah Khan, kexec, linux-doc
On Sun, 20 Sep 2026 22:27:56 -0400 Zi Yan <ziy@nvidia.com> wrote:
> Hi all,
>
> This patchset removes PG_private to make space for upcoming PG_folio for
> identifying pages from a folio (more details in Note below). Instead of
> checking PG_private, all code is changed to check page/folio->private !=
> NULL instead.
Thanks, I updated mm-unstable to this version.
> Changes in v5:
> 1. replaced md patches (patch 13 and 14 in v4) with Matthew Wilcox's
> version (see Matthew's replies to v4).
> 2. used data_race() inside folio_test_private() and PagePrivate(), so that
> the new versions can be used without KCSAN warnings while not holding
> folio lock like before.
> 3. moved folio_has_attached_private() implementation detail comment next to
> the code.
Here's how v5 altered mm.git:
drivers/md/md-bitmap.c | 17 ++++++++---------
fs/buffer.c | 8 --------
include/linux/buffer_head.h | 2 +-
include/linux/mm.h | 3 +--
include/linux/page-flags.h | 30 +++++++++++++++++++-----------
include/trace/events/pagemap.h | 3 +--
mm/huge_memory.c | 3 +--
mm/page-writeback.c | 3 +--
8 files changed, 32 insertions(+), 37 deletions(-)
--- a/drivers/md/md-bitmap.c~b
+++ a/drivers/md/md-bitmap.c
@@ -516,7 +516,8 @@ static void end_bitmap_write(struct bio
static void write_file_page(struct bitmap *bitmap, struct page *page, int wait)
{
- struct buffer_head *bh = (struct buffer_head *)page_private(page);
+ struct folio *folio = page_folio(page);
+ struct buffer_head *bh = folio_buffers(folio);
while (bh && bh->b_blocknr) {
atomic_inc(&bitmap->pending_writes);
@@ -533,18 +534,15 @@ static void write_file_page(struct bitma
static void free_buffers(struct page *page)
{
- struct buffer_head *bh = (struct buffer_head *)page_private(page);
-
- if (!bh)
- return;
+ struct folio *folio = page_folio(page);
+ struct buffer_head *bh = folio_detach_private(folio);
while (bh) {
struct buffer_head *next = bh->b_this_page;
free_buffer_head(bh);
bh = next;
}
- detach_page_private(page);
- put_page(page);
+ folio_put(folio);
}
/* read a page from a file.
@@ -559,6 +557,7 @@ static int read_file_page(struct file *f
{
int ret = 0;
struct inode *inode = file_inode(file);
+ struct folio *folio = page_folio(page);
struct buffer_head *bh;
sector_t block, blk_cur;
unsigned long blocksize = i_blocksize(inode);
@@ -566,12 +565,12 @@ static int read_file_page(struct file *f
pr_debug("read bitmap file (%dB @ %llu)\n", (int)PAGE_SIZE,
(unsigned long long)index << PAGE_SHIFT);
- bh = alloc_page_buffers(page, blocksize);
+ bh = folio_alloc_buffers(folio, blocksize, GFP_NOFS | __GFP_ACCOUNT);
if (!bh) {
ret = -ENOMEM;
goto out;
}
- attach_page_private(page, bh);
+ folio_attach_private(folio, bh);
blk_cur = index << (PAGE_SHIFT - inode->i_blkbits);
while (bh) {
block = blk_cur;
--- a/fs/buffer.c~b
+++ a/fs/buffer.c
@@ -773,14 +773,6 @@ no_grow:
}
EXPORT_SYMBOL_GPL(folio_alloc_buffers);
-struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size)
-{
- gfp_t gfp = GFP_NOFS | __GFP_ACCOUNT;
-
- return folio_alloc_buffers(page_folio(page), size, gfp);
-}
-EXPORT_SYMBOL_GPL(alloc_page_buffers);
-
static inline void link_dev_buffers(struct folio *folio,
struct buffer_head *head)
{
--- a/include/linux/buffer_head.h~b
+++ a/include/linux/buffer_head.h
@@ -175,6 +175,7 @@ static inline unsigned long bh_offset(co
return (unsigned long)(bh)->b_data & (page_size(bh->b_page) - 1);
}
+/* If we *know* folio->private refers to buffer_heads */
#define folio_buffers(folio) folio_get_private(folio)
void buffer_check_dirty_writeback(struct folio *folio,
@@ -191,7 +192,6 @@ void folio_set_bh(struct buffer_head *bh
unsigned long offset);
struct buffer_head *folio_alloc_buffers(struct folio *folio, unsigned long size,
gfp_t gfp);
-struct buffer_head *alloc_page_buffers(struct page *page, unsigned long size);
struct buffer_head *create_empty_buffers(struct folio *folio,
unsigned long blocksize, unsigned long b_state);
void end_buffer_read_sync(struct buffer_head *bh, int uptodate);
--- a/include/linux/mm.h~b
+++ a/include/linux/mm.h
@@ -3052,9 +3052,8 @@ static inline int folio_expected_ref_cou
ref_count += !!data_race(folio->mapping) << order;
/*
* One reference from filesystem private data.
- * Use data_race() since folio might not be locked.
*/
- ref_count += data_race(folio_has_attached_private(folio));
+ ref_count += folio_has_attached_private(folio);
}
/* One reference per page table mapping. */
--- a/include/linux/page-flags.h~b
+++ a/include/linux/page-flags.h
@@ -576,7 +576,12 @@ FOLIO_FLAG(swapbacked, FOLIO_HEAD_PAGE)
static __always_inline bool folio_test_private(const struct folio *folio)
{
- return folio->private;
+ /*
+ * data_race() is added for readers without holding the folio lock.
+ * Only the NULL/non-NULL answer is used and both are valid while
+ * private is being attached or detached, so the race is benign.
+ */
+ return data_race(folio->private);
}
FOLIO_FLAG(private_2, FOLIO_HEAD_PAGE)
@@ -1199,20 +1204,23 @@ static __always_inline void __ClearPageA
* @folio: The folio to check.
*
* Use this in code that may encounter swapcache or hugetlb folios but only
- * wants to detect attached private data. Swapcache stores swp_entry_t in
- * folio->swap, a union with folio->private, and hugetlb stores its own flags
- * in folio->private; both are excluded.
- *
- * NOTE: For swapcache, folio->swap.val PG_swapcache are not set as a whole,
- * so folio_test_swapcache() is not reliable to exclude swapcache.
- * Use folio_test_swapbacked() instead, since it remains set when a folio is
- * added to/removed from swapcache.
+ * wants to detect attached private data.
*
- * Return: true if folio->private is set and the folio is neither swapcache
- * nor hugetlb.
+ * Return: true if the folio has private data attached.
*/
static inline bool folio_has_attached_private(const struct folio *folio)
{
+ /*
+ * Swapcache stores swp_entry_t in folio->swap, a union with
+ * folio->private, and hugetlb stores its own flags in folio->private;
+ * both are excluded.
+ *
+ * NOTE: For swapcache, folio->swap.val PG_swapcache are not set as
+ * a whole, so folio_test_swapcache() is not reliable to exclude
+ * swapcache. Use folio_test_swapbacked() instead, since it remains set
+ * when a folio is added to/removed from swapcache.
+ */
+
return folio_test_private(folio) && !folio_test_swapbacked(folio) &&
!folio_test_hugetlb(folio);
}
--- a/include/trace/events/pagemap.h~b
+++ a/include/trace/events/pagemap.h
@@ -22,8 +22,7 @@
(folio_test_swapcache(folio) ? PAGEMAP_SWAPCACHE : 0) | \
(folio_test_swapbacked(folio) ? PAGEMAP_SWAPBACKED : 0) | \
(folio_test_mappedtodisk(folio) ? PAGEMAP_MAPPEDDISK : 0) | \
- /* data_race() is used to read attached private locklessly */ \
- (data_race(folio_has_attached_private(folio)) ? PAGEMAP_BUFFERS : 0) \
+ (folio_has_attached_private(folio) ? PAGEMAP_BUFFERS : 0) \
)
TRACE_EVENT(mm_lru_insertion,
--- a/mm/huge_memory.c~b
+++ a/mm/huge_memory.c
@@ -4845,9 +4845,8 @@ static int split_huge_pages_pid(int pid,
* For folios with private, split_huge_page_to_list_to_order()
* will try to drop it before split and then check if the folio
* can be split or not. So skip the check here.
- * data_race() is used to read attached private locklessly.
*/
- if (!data_race(folio_has_attached_private(folio)) &&
+ if (!folio_has_attached_private(folio) &&
folio_expected_ref_count(folio) != folio_ref_count(folio))
goto next;
--- a/mm/page-writeback.c~b
+++ a/mm/page-writeback.c
@@ -2705,8 +2705,7 @@ bool filemap_dirty_folio(struct address_
if (folio_test_set_dirty(folio))
return false;
- /* data_race() is used to read attached private locklessly */
- __folio_mark_dirty(folio, mapping, !data_race(folio_has_attached_private(folio)));
+ __folio_mark_dirty(folio, mapping, !folio_has_attached_private(folio));
if (mapping->host) {
/* !PageAnon && !swapper_space */
_
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 02/17] perf/ring_buffer: stop using PG_private as AUX page high-order marker
2026-09-21 2:27 ` [PATCH v5 02/17] perf/ring_buffer: stop using PG_private as AUX page high-order marker Zi Yan
2026-09-21 2:38 ` sashiko-bot
@ 2026-09-21 6:19 ` Lance Yang
1 sibling, 0 replies; 7+ messages in thread
From: Lance Yang @ 2026-09-21 6:19 UTC (permalink / raw)
To: Zi Yan
Cc: linux-mm, Suren Baghdasaryan, linux-kernel, Ryan Roberts,
Johannes Weiner, David Hildenbrand, Nico Pache, Peter Zijlstra,
Lorenzo Stoakes, Mike Rapoport, Matthew Wilcox (Oracle),
Usama Arif, Barry Song, Dev Jain, Ingo Molnar, Andrew Morton,
Alistair Popple, Qi Zheng, Liam R. Howlett,
Arnaldo Carvalho de Melo, Namhyung Kim, Thomas Gleixner,
Borislav Petkov, Kairui Song, Shakeel Butt, Dave Hansen, x86,
Mark Rutland, Alexander Shishkin, Jiri Olsa, Ian Rogers,
Adrian Hunter, James Clark, H. Peter Anvin, linux-perf-users,
Gregory Price, Ying Huang, Baolin Wang, Michal Hocko,
Vlastimil Babka, Muchun Song
On 2026/9/21 10:27, Zi Yan wrote:
> A high-order AUX page sets PG_private on its first page and stores the
> order in first_page->private. Stop using PG_private and check
> first_page->private for AUX page order only in the ring buffer and its
> users. This is fine because page->private is 0 for order-0 AUX pages,
> matching the page order.
>
> It prepares for a future commit that remove PG_private.
>
> No functional change intended.
>
> Assisted-by: LLM
> To: Peter Zijlstra <peterz@infradead.org>
> To: Ingo Molnar <mingo@redhat.com>
> To: Arnaldo Carvalho de Melo <acme@kernel.org>
> To: Namhyung Kim <namhyung@kernel.org>
> To: Thomas Gleixner <tglx@kernel.org>
> To: Borislav Petkov <bp@alien8.de>
> To: Dave Hansen <dave.hansen@linux.intel.com>
> To: x86@kernel.org
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> Cc: Jiri Olsa <jolsa@kernel.org>
> Cc: Ian Rogers <irogers@google.com>
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Cc: James Clark <james.clark@linaro.org>
> Cc: "H. Peter Anvin" <hpa@zytor.com>
> Cc: linux-perf-users@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Acked-by: Usama Arif <usama.arif@linux.dev>
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
> Signed-off-by: Zi Yan <ziy@nvidia.com>
> ---
Nice cleanup! Feel free to add:
Reviewed-by: Lance Yang <lance.yang@linux.dev>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 00/17] Remove PG_private by using page/folio->private checks instead
2026-09-21 2:27 [PATCH v5 00/17] Remove PG_private by using page/folio->private checks instead Zi Yan
2026-09-21 2:27 ` [PATCH v5 02/17] perf/ring_buffer: stop using PG_private as AUX page high-order marker Zi Yan
2026-09-21 4:08 ` [PATCH v5 00/17] Remove PG_private by using page/folio->private checks instead Andrew Morton
@ 2026-09-22 4:16 ` Nanzhe Zhao
2026-09-22 15:31 ` [f2fs-dev] " Jaegeuk Kim
2 siblings, 1 reply; 7+ messages in thread
From: Nanzhe Zhao @ 2026-09-22 4:16 UTC (permalink / raw)
To: Zi Yan
Cc: David Hildenbrand, Matthew Wilcox (Oracle), Andrew Morton,
Muchun Song, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Baolin Wang,
Nico Pache, Ryan Roberts, Dev Jain, Barry Song, Lance Yang,
Usama Arif, Gregory Price, Ying Huang, Alistair Popple,
Johannes Weiner, Qi Zheng, Shakeel Butt, Kairui Song,
Mark Rutland, Ian Rogers, Jan Kara, linux-doc, Alex Markuze,
Peter Zijlstra, kexec, Dave Hansen, Dave Young, Adrian Hunter,
linux-mm, Hongbo Li, H. Peter Anvin, Chunhai Guo, Shuah Khan,
Tal Zussman, Baoquan He, Matthew Brost, Anna Schumaker,
Stefano Stabellini, Yue Hu, Rakie Kim, Minchan Kim,
Richard Weinberger, x86, ceph-devel, Eric Biggers,
Alexander Shishkin, Ingo Molnar, Viacheslav Dubeyko, Wei Xu,
xen-devel, Gao Xiang, Masami Hiramatsu, Joshua Hahn,
Byungchul Park, James Clark, Arnaldo Carvalho de Melo,
linux-fscrypt, Borislav Petkov, Steven Rostedt, linux-mtd,
Axel Rasmussen, Jeffle Xu, Namhyung Kim, Jaegeuk Kim, Yuanchu Xie,
Ilya Dryomov, Oscar Salvador, Juergen Gross, Pratyush Yadav,
linux-nfs, Theodore Y. Ts'o, Oleksandr Tyshchenko,
Jonathan Corbet, Pasha Tatashin, linux-kernel, linux-f2fs-devel,
linux-perf-users, Sergey Senozhatsky, Thomas Gleixner, Jiri Olsa,
linux-fsdevel, Mathieu Desnoyers, linux-trace-kernel, linux-erofs,
Trond Myklebust, Chao Yu, Daeho Jeong
Hi Zi Yan,
Thanks for the series. The cleanup is a nice help for the f2fs
large-folio work -- it removes the page-based private-flag plumbing that
my series would otherwise have to carry itself.
My large-folio series v2 [1] can be rebased on top of this series. The
only overlap is the PAGE_PRIVATE_* flag helpers, which I can re-express
on top of the F2FS_FOLIO_PRIVATE_* names while keeping the
f2fs_folio_state indirection.
Jaegeuk, do you have a preference on the ordering here? My personal
suggestion would be to review and merge this series first, and I'll
rebase on top of it.
[1] https://lore.kernel.org/linux-f2fs-devel/20260915041909.2903887-1-zhaonanzhe@xiaomi.com/
Thanks,
Nanzhe
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [f2fs-dev] [PATCH v5 00/17] Remove PG_private by using page/folio->private checks instead
2026-09-22 4:16 ` Nanzhe Zhao
@ 2026-09-22 15:31 ` Jaegeuk Kim
0 siblings, 0 replies; 7+ messages in thread
From: Jaegeuk Kim @ 2026-09-22 15:31 UTC (permalink / raw)
To: Nanzhe Zhao
Cc: Zi Yan, Qi Zheng, Matthew Brost, Alistair Popple, ceph-devel,
Eric Biggers, xen-devel, Gregory Price, Arnaldo Carvalho de Melo,
linux-fscrypt, Shuah Khan, David Hildenbrand, Suren Baghdasaryan,
linux-kernel, Nico Pache, linux-perf-users, Oleksandr Tyshchenko,
Masami Hiramatsu, Jiri Olsa, linux-fsdevel, Andrew Morton,
Trond Myklebust, Mark Rutland, linux-doc, Dave Hansen, Hongbo Li,
Ying Huang, Stefano Stabellini, Vlastimil Babka,
Sergey Senozhatsky, Byungchul Park, linux-trace-kernel,
Lorenzo Stoakes, Joshua Hahn, Barry Song, Kairui Song,
Theodore Y. Ts'o, Muchun Song, linux-f2fs-devel, Minchan Kim,
Lance Yang, Thomas Gleixner, Anna Schumaker, Pratyush Yadav,
Alex Markuze, Alexander Shishkin, linux-mtd, Chunhai Guo,
Jonathan Corbet, Dev Jain, Matthew Wilcox (Oracle),
Viacheslav Dubeyko, Gao Xiang, Wei Xu, Baoquan He, James Clark,
Steven Rostedt, Borislav Petkov, Baolin Wang, Shakeel Butt,
Tal Zussman, Ilya Dryomov, Oscar Salvador, linux-nfs, linux-mm,
linux-erofs, Mike Rapoport, Ian Rogers, Michal Hocko, Jan Kara,
Peter Zijlstra, Dave Young, Yuanchu Xie, Liam R. Howlett,
H. Peter Anvin, Yue Hu, Rakie Kim, Richard Weinberger, x86,
Ingo Molnar, Axel Rasmussen, Ryan Roberts, Pasha Tatashin,
Usama Arif, Jeffle Xu, Namhyung Kim, Juergen Gross, kexec,
Adrian Hunter, Johannes Weiner, Mathieu Desnoyers
On 09/22, Nanzhe Zhao wrote:
> Hi Zi Yan,
>
> Thanks for the series. The cleanup is a nice help for the f2fs
> large-folio work -- it removes the page-based private-flag plumbing that
> my series would otherwise have to carry itself.
>
> My large-folio series v2 [1] can be rebased on top of this series. The
> only overlap is the PAGE_PRIVATE_* flag helpers, which I can re-express
> on top of the F2FS_FOLIO_PRIVATE_* names while keeping the
> f2fs_folio_state indirection.
>
> Jaegeuk, do you have a preference on the ordering here? My personal
> suggestion would be to review and merge this series first, and I'll
> rebase on top of it.
Let's keep working on the f2fs tree, since we should not merge this in my tree.
Later, we'd need to prepare how to address the merge conflict.
>
> [1] https://lore.kernel.org/linux-f2fs-devel/20260915041909.2903887-1-zhaonanzhe@xiaomi.com/
>
> Thanks,
> Nanzhe
>
>
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-09-22 15:31 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-21 2:27 [PATCH v5 00/17] Remove PG_private by using page/folio->private checks instead Zi Yan
2026-09-21 2:27 ` [PATCH v5 02/17] perf/ring_buffer: stop using PG_private as AUX page high-order marker Zi Yan
2026-09-21 2:38 ` sashiko-bot
2026-09-21 6:19 ` Lance Yang
2026-09-21 4:08 ` [PATCH v5 00/17] Remove PG_private by using page/folio->private checks instead Andrew Morton
2026-09-22 4:16 ` Nanzhe Zhao
2026-09-22 15:31 ` [f2fs-dev] " Jaegeuk Kim
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox