* [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private
2026-09-08 2:56 [PATCH v3 00/14] Remove PG_private by using page/folio->private checks instead Zi Yan
@ 2026-09-08 2:56 ` Zi Yan
2026-09-08 16:04 ` David Hildenbrand (Arm)
2026-09-08 2:56 ` [PATCH v3 09/14] mm/page-flags: check page/folio->private instead of PG_private Zi Yan
` (3 subsequent siblings)
4 siblings, 1 reply; 19+ messages in thread
From: Zi Yan @ 2026-09-08 2:56 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, Gao Xiang, Chao Yu, Jan Kara,
Yue Hu, Jeffle Xu, Sandeep Dhavale, Hongbo Li, Chunhai Guo,
linux-erofs, linux-fsdevel
erofs needs to traverse readahead folios in reverse order to achieve
maximum performance by
1. reading all folios from readahead_folio();
2. storing the prior folio pointer in folio->private;
3. traverse from the last folio to the first one.
Add readahead_folio_last() to achieve the same function without using
folio->private. __readahead_advance() helper shares readahead_control
adjustment code among __readahead_folio(), readahead_folio_last(), and
__readahead_batch() by checking new private member, _forward, of
readahead_control.
It prepares for a future commit that replaces PG_private checks with
!folio->private checks. After switching the checks, erofs's use of
folio->private without bumping folio refcount can cause unexpected
outcomes, e.g., in filemap_release_folio(), try_to_free_buffers() becomes
reachable.
No functional change intended.
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5
Signed-off-by: Zi Yan <ziy@nvidia.com>
To: Gao Xiang <xiang@kernel.org>
To: Chao Yu <chao@kernel.org>
To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
To: Jan Kara <jack@suse.cz>
Cc: Yue Hu <zbestahu@gmail.com>
Cc: Jeffle Xu <jefflexu@linux.alibaba.com>
Cc: Sandeep Dhavale <dhavale@google.com>
Cc: Hongbo Li <hongbohbli@tencent.com>
Cc: Chunhai Guo <guochunhai@vivo.com>
Cc: linux-erofs@lists.ozlabs.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
---
fs/erofs/zdata.c | 13 +++---------
include/linux/pagemap.h | 56 ++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 51 insertions(+), 18 deletions(-)
diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
index e1e25ca0d1904..78fd7d980e957 100644
--- a/fs/erofs/zdata.c
+++ b/fs/erofs/zdata.c
@@ -1898,21 +1898,14 @@ static void z_erofs_readahead(struct readahead_control *rac)
struct inode *realinode = erofs_real_inode(sharedinode, &need_iput);
Z_EROFS_DEFINE_FRONTEND(f, realinode, sharedinode, readahead_pos(rac));
unsigned int nrpages = readahead_count(rac);
- struct folio *head = NULL, *folio;
+ struct folio *folio;
int err;
trace_erofs_readahead(realinode, readahead_index(rac), nrpages, false);
z_erofs_pcluster_readmore(&f, rac, true);
- while ((folio = readahead_folio(rac))) {
- folio->private = head;
- head = folio;
- }
-
- /* traverse in reverse order for best metadata I/O performance */
- while (head) {
- folio = head;
- head = folio_get_private(folio);
+ /* traverse from last to first for best metadata I/O performance */
+ while ((folio = readahead_folio_last(rac))) {
err = z_erofs_scan_folio(&f, folio, true);
if (err && err != -EINTR)
erofs_err(realinode->i_sb, "readahead error at folio %lu @ nid %llu",
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 939f3a5e973f6..2257df004305e 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -1415,6 +1415,7 @@ struct readahead_control {
bool dropbehind;
bool _workingset;
unsigned long _pflags;
+ bool _forward;
};
#define DEFINE_READAHEAD(ractl, f, r, m, i) \
@@ -1479,18 +1480,25 @@ void page_cache_async_readahead(struct address_space *mapping,
page_cache_async_ra(&ractl, folio, req_count);
}
+static inline void __readahead_advance(struct readahead_control *rac)
+{
+ if (rac->_forward)
+ rac->_index += rac->_batch_count;
+
+ rac->_nr_pages -= rac->_batch_count;
+ rac->_batch_count = 0;
+}
+
static inline struct folio *__readahead_folio(struct readahead_control *ractl)
{
struct folio *folio;
BUG_ON(ractl->_batch_count > ractl->_nr_pages);
- ractl->_nr_pages -= ractl->_batch_count;
- ractl->_index += ractl->_batch_count;
+ __readahead_advance(ractl);
+ ractl->_forward = true;
- if (!ractl->_nr_pages) {
- ractl->_batch_count = 0;
+ if (!ractl->_nr_pages)
return NULL;
- }
folio = xa_load(&ractl->mapping->i_pages, ractl->_index);
VM_BUG_ON_FOLIO(!folio_test_locked(folio), folio);
@@ -1516,6 +1524,39 @@ static inline struct folio *readahead_folio(struct readahead_control *ractl)
return folio;
}
+/**
+ * readahead_folio_last - Get the next folio to read, from the tail.
+ * @ractl: The current readahead request.
+ *
+ * Like readahead_folio(), but walks the range back-to-front. The folio is
+ * returned locked with its refcount dropped; the caller unlocks it once I/O
+ * completes. Compound folios are returned once, at their head index.
+ *
+ * Context: The folio is locked.
+ * Return: A pointer to the next folio, or %NULL when done.
+ */
+static inline struct folio *readahead_folio_last(struct readahead_control *ractl)
+{
+ struct folio *folio;
+
+ /* Drop the previously returned batch from the remaining range. */
+ __readahead_advance(ractl);
+ ractl->_forward = false;
+
+ if (!ractl->_nr_pages)
+ return NULL;
+
+ /* xa_load() follows sibling entries, so a tail index returns the head */
+ folio = xa_load(&ractl->mapping->i_pages,
+ ractl->_index + ractl->_nr_pages - 1);
+ VM_WARN_ON_ONCE_FOLIO(!folio_test_locked(folio), folio);
+
+ ractl->_batch_count = folio_nr_pages(folio);
+
+ folio_put(folio);
+ return folio;
+}
+
static inline unsigned int __readahead_batch(struct readahead_control *rac,
struct page **array, unsigned int array_sz)
{
@@ -1524,9 +1565,8 @@ static inline unsigned int __readahead_batch(struct readahead_control *rac,
struct folio *folio;
BUG_ON(rac->_batch_count > rac->_nr_pages);
- rac->_nr_pages -= rac->_batch_count;
- rac->_index += rac->_batch_count;
- rac->_batch_count = 0;
+ __readahead_advance(rac);
+ rac->_forward = true;
xas_set(&xas, rac->_index);
rcu_read_lock();
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private
2026-09-08 2:56 ` [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private Zi Yan
@ 2026-09-08 16:04 ` David Hildenbrand (Arm)
2026-09-08 17:05 ` Zi Yan
0 siblings, 1 reply; 19+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-08 16:04 UTC (permalink / raw)
To: Zi Yan, 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, Gao Xiang, Chao Yu, Jan Kara, Yue Hu,
Jeffle Xu, Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs,
linux-fsdevel
On 9/8/26 04:56, Zi Yan wrote:
> erofs needs to traverse readahead folios in reverse order to achieve
> maximum performance by
> 1. reading all folios from readahead_folio();
> 2. storing the prior folio pointer in folio->private;
> 3. traverse from the last folio to the first one.
>
> Add readahead_folio_last() to achieve the same function without using
> folio->private. __readahead_advance() helper shares readahead_control
> adjustment code among __readahead_folio(), readahead_folio_last(), and
> __readahead_batch() by checking new private member, _forward, of
> readahead_control.
>
> It prepares for a future commit that replaces PG_private checks with
> !folio->private checks. After switching the checks, erofs's use of
> folio->private without bumping folio refcount can cause unexpected
> outcomes, e.g., in filemap_release_folio(), try_to_free_buffers() becomes
> reachable.
Ah, I was just about to ask. So it's really about folios never using
folio->private manually (without the attach/detach).
>
> No functional change intended.
>
> Assisted-by: Claude:claude-opus-4-8
> Assisted-by: Codex:gpt-5
> Signed-off-by: Zi Yan <ziy@nvidia.com>
> To: Gao Xiang <xiang@kernel.org>
> To: Chao Yu <chao@kernel.org>
> To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> To: Jan Kara <jack@suse.cz>
> Cc: Yue Hu <zbestahu@gmail.com>
> Cc: Jeffle Xu <jefflexu@linux.alibaba.com>
> Cc: Sandeep Dhavale <dhavale@google.com>
> Cc: Hongbo Li <hongbohbli@tencent.com>
> Cc: Chunhai Guo <guochunhai@vivo.com>
> Cc: linux-erofs@lists.ozlabs.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org
> Cc: linux-mm@kvack.org
> ---
> fs/erofs/zdata.c | 13 +++---------
> include/linux/pagemap.h | 56 ++++++++++++++++++++++++++++++++++++++++++-------
> 2 files changed, 51 insertions(+), 18 deletions(-)
>
> diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
> index e1e25ca0d1904..78fd7d980e957 100644
> --- a/fs/erofs/zdata.c
> +++ b/fs/erofs/zdata.c
> @@ -1898,21 +1898,14 @@ static void z_erofs_readahead(struct readahead_control *rac)
> struct inode *realinode = erofs_real_inode(sharedinode, &need_iput);
> Z_EROFS_DEFINE_FRONTEND(f, realinode, sharedinode, readahead_pos(rac));
> unsigned int nrpages = readahead_count(rac);
> - struct folio *head = NULL, *folio;
> + struct folio *folio;
> int err;
>
> trace_erofs_readahead(realinode, readahead_index(rac), nrpages, false);
> z_erofs_pcluster_readmore(&f, rac, true);
> - while ((folio = readahead_folio(rac))) {
> - folio->private = head;
> - head = folio;
> - }
> -
> - /* traverse in reverse order for best metadata I/O performance */
> - while (head) {
> - folio = head;
> - head = folio_get_private(folio);
>
> + /* traverse from last to first for best metadata I/O performance */
> + while ((folio = readahead_folio_last(rac))) {
Intuitively, this should be called readahead_folio_reverse /
readahead_folio_reversed, thinking of list_for_each_entry_reverse()?
list_for_each_entry_reverse - iterate backwards over list of given type.
or maybe readahead_folio_backwards (which matches the forward below)
But I'm not a readahead expert :)
> err = z_erofs_scan_folio(&f, folio, true);
> if (err && err != -EINTR)
> erofs_err(realinode->i_sb, "readahead error at folio %lu @ nid %llu",
> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
> index 939f3a5e973f6..2257df004305e 100644
> --- a/include/linux/pagemap.h
> +++ b/include/linux/pagemap.h
> @@ -1415,6 +1415,7 @@ struct readahead_control {
> bool dropbehind;
> bool _workingset;
> unsigned long _pflags;
> + bool _forward;
> };
>
> #define DEFINE_READAHEAD(ractl, f, r, m, i) \
> @@ -1479,18 +1480,25 @@ void page_cache_async_readahead(struct address_space *mapping,
> page_cache_async_ra(&ractl, folio, req_count);
> }
>
> +static inline void __readahead_advance(struct readahead_control *rac)
> +{
> + if (rac->_forward)
> + rac->_index += rac->_batch_count;
No expert, but shouldn't we decrement the _index somewhere in the other case? Or
where is that done? A comment might help :)
--
Cheers,
David
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private
2026-09-08 16:04 ` David Hildenbrand (Arm)
@ 2026-09-08 17:05 ` Zi Yan
2026-09-09 14:10 ` David Hildenbrand (Arm)
0 siblings, 1 reply; 19+ messages in thread
From: Zi Yan @ 2026-09-08 17:05 UTC (permalink / raw)
To: David Hildenbrand (Arm), 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, Gao Xiang, Chao Yu, Jan Kara, Yue Hu,
Jeffle Xu, Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs,
linux-fsdevel
On Tue Sep 8, 2026 at 12:04 PM EDT, David Hildenbrand (Arm) wrote:
> On 9/8/26 04:56, Zi Yan wrote:
>> erofs needs to traverse readahead folios in reverse order to achieve
>> maximum performance by
>> 1. reading all folios from readahead_folio();
>> 2. storing the prior folio pointer in folio->private;
>> 3. traverse from the last folio to the first one.
>>
>> Add readahead_folio_last() to achieve the same function without using
>> folio->private. __readahead_advance() helper shares readahead_control
>> adjustment code among __readahead_folio(), readahead_folio_last(), and
>> __readahead_batch() by checking new private member, _forward, of
>> readahead_control.
>>
>> It prepares for a future commit that replaces PG_private checks with
>> !folio->private checks. After switching the checks, erofs's use of
>> folio->private without bumping folio refcount can cause unexpected
>> outcomes, e.g., in filemap_release_folio(), try_to_free_buffers() becomes
>> reachable.
>
> Ah, I was just about to ask. So it's really about folios never using
> folio->private manually (without the attach/detach).
>
>>
>> No functional change intended.
>>
>> Assisted-by: Claude:claude-opus-4-8
>> Assisted-by: Codex:gpt-5
>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>> To: Gao Xiang <xiang@kernel.org>
>> To: Chao Yu <chao@kernel.org>
>> To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
>> To: Jan Kara <jack@suse.cz>
>> Cc: Yue Hu <zbestahu@gmail.com>
>> Cc: Jeffle Xu <jefflexu@linux.alibaba.com>
>> Cc: Sandeep Dhavale <dhavale@google.com>
>> Cc: Hongbo Li <hongbohbli@tencent.com>
>> Cc: Chunhai Guo <guochunhai@vivo.com>
>> Cc: linux-erofs@lists.ozlabs.org
>> Cc: linux-kernel@vger.kernel.org
>> Cc: linux-fsdevel@vger.kernel.org
>> Cc: linux-mm@kvack.org
>> ---
>> fs/erofs/zdata.c | 13 +++---------
>> include/linux/pagemap.h | 56 ++++++++++++++++++++++++++++++++++++++++++-------
>> 2 files changed, 51 insertions(+), 18 deletions(-)
>>
>> diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
>> index e1e25ca0d1904..78fd7d980e957 100644
>> --- a/fs/erofs/zdata.c
>> +++ b/fs/erofs/zdata.c
>> @@ -1898,21 +1898,14 @@ static void z_erofs_readahead(struct readahead_control *rac)
>> struct inode *realinode = erofs_real_inode(sharedinode, &need_iput);
>> Z_EROFS_DEFINE_FRONTEND(f, realinode, sharedinode, readahead_pos(rac));
>> unsigned int nrpages = readahead_count(rac);
>> - struct folio *head = NULL, *folio;
>> + struct folio *folio;
>> int err;
>>
>> trace_erofs_readahead(realinode, readahead_index(rac), nrpages, false);
>> z_erofs_pcluster_readmore(&f, rac, true);
>> - while ((folio = readahead_folio(rac))) {
>> - folio->private = head;
>> - head = folio;
>> - }
>> -
>> - /* traverse in reverse order for best metadata I/O performance */
>> - while (head) {
>> - folio = head;
>> - head = folio_get_private(folio);
>>
>> + /* traverse from last to first for best metadata I/O performance */
>> + while ((folio = readahead_folio_last(rac))) {
>
> Intuitively, this should be called readahead_folio_reverse /
> readahead_folio_reversed, thinking of list_for_each_entry_reverse()?
>
> list_for_each_entry_reverse - iterate backwards over list of given type.
>
> or maybe readahead_folio_backwards (which matches the forward below)
>
> But I'm not a readahead expert :)
Jan suggested the name[1]. It can be readahead_folio_reverse() if you
prefer it, like Jan said.
[1] https://lore.kernel.org/all/332rknj4vo3cfhvfhhlf6pvg37s3lbrnzbbnv4swa6gctsiu6a@ndotgokvnglc/
>
>> err = z_erofs_scan_folio(&f, folio, true);
>> if (err && err != -EINTR)
>> erofs_err(realinode->i_sb, "readahead error at folio %lu @ nid %llu",
>> diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
>> index 939f3a5e973f6..2257df004305e 100644
>> --- a/include/linux/pagemap.h
>> +++ b/include/linux/pagemap.h
>> @@ -1415,6 +1415,7 @@ struct readahead_control {
>> bool dropbehind;
>> bool _workingset;
>> unsigned long _pflags;
>> + bool _forward;
>> };
>>
>> #define DEFINE_READAHEAD(ractl, f, r, m, i) \
>> @@ -1479,18 +1480,25 @@ void page_cache_async_readahead(struct address_space *mapping,
>> page_cache_async_ra(&ractl, folio, req_count);
>> }
>>
>> +static inline void __readahead_advance(struct readahead_control *rac)
>> +{
>> + if (rac->_forward)
>> + rac->_index += rac->_batch_count;
>
> No expert, but shouldn't we decrement the _index somewhere in the other case? Or
> where is that done? A comment might help :)
A readahead folio comes from [_index, _index + _nr_pages), so for
last/reverse/backwards case, the code only needs to decrease _nr_pages.
Will add a comment about this.
--
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private
2026-09-08 17:05 ` Zi Yan
@ 2026-09-09 14:10 ` David Hildenbrand (Arm)
0 siblings, 0 replies; 19+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-09 14:10 UTC (permalink / raw)
To: Zi Yan, 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, Gao Xiang, Chao Yu, Jan Kara, Yue Hu,
Jeffle Xu, Sandeep Dhavale, Hongbo Li, Chunhai Guo, linux-erofs,
linux-fsdevel
On 9/8/26 19:05, Zi Yan wrote:
> On Tue Sep 8, 2026 at 12:04 PM EDT, David Hildenbrand (Arm) wrote:
>> On 9/8/26 04:56, Zi Yan wrote:
>>> erofs needs to traverse readahead folios in reverse order to achieve
>>> maximum performance by
>>> 1. reading all folios from readahead_folio();
>>> 2. storing the prior folio pointer in folio->private;
>>> 3. traverse from the last folio to the first one.
>>>
>>> Add readahead_folio_last() to achieve the same function without using
>>> folio->private. __readahead_advance() helper shares readahead_control
>>> adjustment code among __readahead_folio(), readahead_folio_last(), and
>>> __readahead_batch() by checking new private member, _forward, of
>>> readahead_control.
>>>
>>> It prepares for a future commit that replaces PG_private checks with
>>> !folio->private checks. After switching the checks, erofs's use of
>>> folio->private without bumping folio refcount can cause unexpected
>>> outcomes, e.g., in filemap_release_folio(), try_to_free_buffers() becomes
>>> reachable.
>>
>> Ah, I was just about to ask. So it's really about folios never using
>> folio->private manually (without the attach/detach).
>>
>>>
>>> No functional change intended.
>>>
>>> Assisted-by: Claude:claude-opus-4-8
>>> Assisted-by: Codex:gpt-5
>>> Signed-off-by: Zi Yan <ziy@nvidia.com>
>>> To: Gao Xiang <xiang@kernel.org>
>>> To: Chao Yu <chao@kernel.org>
>>> To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
>>> To: Jan Kara <jack@suse.cz>
>>> Cc: Yue Hu <zbestahu@gmail.com>
>>> Cc: Jeffle Xu <jefflexu@linux.alibaba.com>
>>> Cc: Sandeep Dhavale <dhavale@google.com>
>>> Cc: Hongbo Li <hongbohbli@tencent.com>
>>> Cc: Chunhai Guo <guochunhai@vivo.com>
>>> Cc: linux-erofs@lists.ozlabs.org
>>> Cc: linux-kernel@vger.kernel.org
>>> Cc: linux-fsdevel@vger.kernel.org
>>> Cc: linux-mm@kvack.org
>>> ---
>>> fs/erofs/zdata.c | 13 +++---------
>>> include/linux/pagemap.h | 56 ++++++++++++++++++++++++++++++++++++++++++-------
>>> 2 files changed, 51 insertions(+), 18 deletions(-)
>>>
>>> diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
>>> index e1e25ca0d1904..78fd7d980e957 100644
>>> --- a/fs/erofs/zdata.c
>>> +++ b/fs/erofs/zdata.c
>>> @@ -1898,21 +1898,14 @@ static void z_erofs_readahead(struct readahead_control *rac)
>>> struct inode *realinode = erofs_real_inode(sharedinode, &need_iput);
>>> Z_EROFS_DEFINE_FRONTEND(f, realinode, sharedinode, readahead_pos(rac));
>>> unsigned int nrpages = readahead_count(rac);
>>> - struct folio *head = NULL, *folio;
>>> + struct folio *folio;
>>> int err;
>>>
>>> trace_erofs_readahead(realinode, readahead_index(rac), nrpages, false);
>>> z_erofs_pcluster_readmore(&f, rac, true);
>>> - while ((folio = readahead_folio(rac))) {
>>> - folio->private = head;
>>> - head = folio;
>>> - }
>>> -
>>> - /* traverse in reverse order for best metadata I/O performance */
>>> - while (head) {
>>> - folio = head;
>>> - head = folio_get_private(folio);
>>>
>>> + /* traverse from last to first for best metadata I/O performance */
>>> + while ((folio = readahead_folio_last(rac))) {
>>
>> Intuitively, this should be called readahead_folio_reverse /
>> readahead_folio_reversed, thinking of list_for_each_entry_reverse()?
>>
>> list_for_each_entry_reverse - iterate backwards over list of given type.
>>
>> or maybe readahead_folio_backwards (which matches the forward below)
>>
>> But I'm not a readahead expert :)
>
> Jan suggested the name[1]. It can be readahead_folio_reverse() if you
> prefer it, like Jan said.
>
> [1] https://lore.kernel.org/all/332rknj4vo3cfhvfhhlf6pvg37s3lbrnzbbnv4swa6gctsiu6a@ndotgokvnglc/
Heh, to me _reverse() is clearer; whatever people prefer.
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v3 09/14] mm/page-flags: check page/folio->private instead of PG_private
2026-09-08 2:56 [PATCH v3 00/14] Remove PG_private by using page/folio->private checks instead Zi Yan
2026-09-08 2:56 ` [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private Zi Yan
@ 2026-09-08 2:56 ` Zi Yan
2026-09-08 16:56 ` David Hildenbrand (Arm)
2026-09-08 2:56 ` [PATCH v3 10/14] mm/page-flags: introduce folio_test_fs_private() Zi Yan
` (2 subsequent siblings)
4 siblings, 1 reply; 19+ messages in thread
From: Zi Yan @ 2026-09-08 2:56 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, Steven Rostedt, Masami Hiramatsu,
Jan Kara, Mathieu Desnoyers, Matthew Brost, Joshua Hahn,
Rakie Kim, Byungchul Park, Axel Rasmussen, Yuanchu Xie, Wei Xu,
linux-fsdevel, linux-trace-kernel
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. PG_swapcache and folio->swap.val cannot be set/clear
as a whole, so excluding swapcache with folio_test_swapcache() is not
reliable. Instead, use folio_test_swapbacked(), since PG_swapbacked is
stable when a folio is added to/removed from swapcache.
folio_expected_ref_count() can be called without folio lock, so annotate
folio_test_private() with data_race() to avoid triggering race condition
checks. While at it, annotate folio->mapping too. Add data_race()
annotation for other lockless callers too.
folio_set/clear_private() and Set/ClearPagePrivate() become no-ops.
PG_private is no longer checked at page free time.
Remove KPF_PRIVATE since PG_private is no longer used.
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 | 1 -
include/linux/kernel-page-flags.h | 1 -
include/linux/mm.h | 22 +++++++++++++++-------
include/linux/page-flags.h | 26 +++++++++++++++++++++-----
include/trace/events/pagemap.h | 5 ++++-
mm/huge_memory.c | 5 ++++-
mm/migrate.c | 3 ++-
mm/page-writeback.c | 6 +++++-
mm/vmscan.c | 3 ++-
tools/mm/page-types.c | 2 --
10 files changed, 53 insertions(+), 21 deletions(-)
diff --git a/fs/proc/page.c b/fs/proc/page.c
index 260772b20bd99..f90e1030825e9 100644
--- a/fs/proc/page.c
+++ b/fs/proc/page.c
@@ -232,7 +232,6 @@ 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);
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/kernel-page-flags.h b/include/linux/kernel-page-flags.h
index 196778a087c4d..fe5ab6e50bd70 100644
--- a/include/linux/kernel-page-flags.h
+++ b/include/linux/kernel-page-flags.h
@@ -11,7 +11,6 @@
#define KPF_RESERVED 32
#define KPF_MLOCKED 33
#define KPF_OWNER_2 34
-#define KPF_PRIVATE 35
#define KPF_PRIVATE_2 36
#define KPF_OWNER_PRIVATE 37
#define KPF_ARCH 38
diff --git a/include/linux/mm.h b/include/linux/mm.h
index c49ef99b4413b..5eb8a62fafb56 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3004,9 +3004,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),
@@ -3044,10 +3044,18 @@ static inline int folio_expected_ref_count(const struct folio *folio)
ref_count += folio_test_swapcache(folio) << order;
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 per page from the pagecache.
+ * Use data_race() since folio might not be locked.
+ */
+ 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_test_private(folio)) &&
+ !folio_test_hugetlb(folio) &&
+ !folio_test_swapbacked(folio);
}
/* One reference per page table mapping. */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 86dd0470da117..9cb4d64739798 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;
+}
+
+/* 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_swapbacked(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..8193f91216822 100644
--- a/include/trace/events/pagemap.h
+++ b/include/trace/events/pagemap.h
@@ -22,7 +22,10 @@
(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) \
+ /* data_race() is used to read folio->private locklessly */ \
+ (data_race(folio_test_private(folio)) && \
+ !folio_test_swapbacked(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 d1ce061601bcd..9b2a9d0794a61 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -4831,8 +4831,11 @@ static int split_huge_pages_pid(int pid, unsigned long vaddr_start,
* 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 folio->private locklessly.
*/
- if (!folio_test_private(folio) &&
+ if (!(data_race(folio_test_private(folio)) &&
+ !folio_test_swapbacked(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 a369d0c95c386..f6befd3ff1c46 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1327,7 +1327,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_swapbacked(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 eeab25d6ce364..02ad49b10be07 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2705,7 +2705,11 @@ 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));
+ /* data_race() is used to read folio->private locklessly */
+ __folio_mark_dirty(folio, mapping,
+ !(data_race(folio_test_private(folio)) &&
+ !folio_test_swapbacked(folio) &&
+ !folio_test_hugetlb(folio)));
if (mapping->host) {
/* !PageAnon && !swapper_space */
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 40d3f1b48a74c..9348ebf9de882 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -978,7 +978,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_swapbacked(folio) &&
+ !folio_test_hugetlb(folio)))
return;
mapping = folio_mapping(folio);
diff --git a/tools/mm/page-types.c b/tools/mm/page-types.c
index 7fc5a8be5997f..47e4781c5fc38 100644
--- a/tools/mm/page-types.c
+++ b/tools/mm/page-types.c
@@ -73,7 +73,6 @@
#define KPF_RESERVED 32
#define KPF_MLOCKED 33
#define KPF_OWNER_2 34
-#define KPF_PRIVATE 35
#define KPF_PRIVATE_2 36
#define KPF_OWNER_PRIVATE 37
#define KPF_ARCH 38
@@ -131,7 +130,6 @@ static const char * const page_flag_names[] = {
[KPF_RESERVED] = "r:reserved",
[KPF_MLOCKED] = "m:mlocked",
[KPF_OWNER_2] = "d:owner_2",
- [KPF_PRIVATE] = "P:private",
[KPF_PRIVATE_2] = "p:private_2",
[KPF_OWNER_PRIVATE] = "O:owner_private",
[KPF_ARCH] = "h:arch",
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH v3 09/14] mm/page-flags: check page/folio->private instead of PG_private
2026-09-08 2:56 ` [PATCH v3 09/14] mm/page-flags: check page/folio->private instead of PG_private Zi Yan
@ 2026-09-08 16:56 ` David Hildenbrand (Arm)
2026-09-10 2:08 ` Zi Yan
0 siblings, 1 reply; 19+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-08 16:56 UTC (permalink / raw)
To: Zi Yan, 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, Steven Rostedt, Masami Hiramatsu,
Jan Kara, Mathieu Desnoyers, Matthew Brost, Joshua Hahn,
Rakie Kim, Byungchul Park, Axel Rasmussen, Yuanchu Xie, Wei Xu,
linux-fsdevel, linux-trace-kernel
On 9/8/26 04:56, 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. PG_swapcache and folio->swap.val cannot be set/clear
> as a whole, so excluding swapcache with folio_test_swapcache() is not
> reliable. Instead, use folio_test_swapbacked(), since PG_swapbacked is
> stable when a folio is added to/removed from swapcache.
>
> folio_expected_ref_count() can be called without folio lock, so annotate
> folio_test_private() with data_race() to avoid triggering race condition
> checks. While at it, annotate folio->mapping too. Add data_race()
> annotation for other lockless callers too.
>
> folio_set/clear_private() and Set/ClearPagePrivate() become no-ops.
> PG_private is no longer checked at page free time.
>
> Remove KPF_PRIVATE since PG_private is no longer used.
>
> 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
> ---
[...]
> /* !PageAnon && !swapper_space */
> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 40d3f1b48a74c..9348ebf9de882 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -978,7 +978,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_swapbacked(folio) &&
> + !folio_test_hugetlb(folio)))
Now that I read that check ... a fourth time? a fifth? I stopped counting :)
Should we have a (in light of folio_attach_private()):
static inline bool folio_has_attached_private(const struct folio *folio)
{
/* Careful, we might get called on unlocked folios. */
if (!data_race(folio->private))
return false;
/* On some folios ->private is used for different purposes. */
return !folio_test_swapbacked(folio) && !folio_test_hugetlb(folio);
}
Of course, adding some nice documentation what having attached private means?
--
Cheers,
David
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v3 09/14] mm/page-flags: check page/folio->private instead of PG_private
2026-09-08 16:56 ` David Hildenbrand (Arm)
@ 2026-09-10 2:08 ` Zi Yan
0 siblings, 0 replies; 19+ messages in thread
From: Zi Yan @ 2026-09-10 2:08 UTC (permalink / raw)
To: David Hildenbrand (Arm), 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, Steven Rostedt, Masami Hiramatsu,
Jan Kara, Mathieu Desnoyers, Matthew Brost, Joshua Hahn,
Rakie Kim, Byungchul Park, Axel Rasmussen, Yuanchu Xie, Wei Xu,
linux-fsdevel, linux-trace-kernel
On Tue Sep 8, 2026 at 12:56 PM EDT, David Hildenbrand (Arm) wrote:
> On 9/8/26 04:56, 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. PG_swapcache and folio->swap.val cannot be set/clear
>> as a whole, so excluding swapcache with folio_test_swapcache() is not
>> reliable. Instead, use folio_test_swapbacked(), since PG_swapbacked is
>> stable when a folio is added to/removed from swapcache.
>>
>> folio_expected_ref_count() can be called without folio lock, so annotate
>> folio_test_private() with data_race() to avoid triggering race condition
>> checks. While at it, annotate folio->mapping too. Add data_race()
>> annotation for other lockless callers too.
>>
>> folio_set/clear_private() and Set/ClearPagePrivate() become no-ops.
>> PG_private is no longer checked at page free time.
>>
>> Remove KPF_PRIVATE since PG_private is no longer used.
>>
>> 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
>> ---
>
> [...]
>
>> /* !PageAnon && !swapper_space */
>> diff --git a/mm/vmscan.c b/mm/vmscan.c
>> index 40d3f1b48a74c..9348ebf9de882 100644
>> --- a/mm/vmscan.c
>> +++ b/mm/vmscan.c
>> @@ -978,7 +978,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_swapbacked(folio) &&
>> + !folio_test_hugetlb(folio)))
>
> Now that I read that check ... a fourth time? a fifth? I stopped counting :)
>
> Should we have a (in light of folio_attach_private()):
>
> static inline bool folio_has_attached_private(const struct folio *folio)
> {
> /* Careful, we might get called on unlocked folios. */
> if (!data_race(folio->private))
> return false;
> /* On some folios ->private is used for different purposes. */
> return !folio_test_swapbacked(folio) && !folio_test_hugetlb(folio);
> }
>
> Of course, adding some nice documentation what having attached private means?
Will squash the next one into this one and use
folio_has_attached_private() instead of folio_test_fs_private(), like we
discussed in Patch 10.
--
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v3 10/14] mm/page-flags: introduce folio_test_fs_private()
2026-09-08 2:56 [PATCH v3 00/14] Remove PG_private by using page/folio->private checks instead Zi Yan
2026-09-08 2:56 ` [PATCH v3 07/14] erofs: mm/pagemap: add readahead_folio_last() to avoid folio->private Zi Yan
2026-09-08 2:56 ` [PATCH v3 09/14] mm/page-flags: check page/folio->private instead of PG_private Zi Yan
@ 2026-09-08 2:56 ` Zi Yan
2026-09-08 16:59 ` David Hildenbrand (Arm)
2026-09-08 2:56 ` [PATCH v3 11/14] treewide: remove folio_set/clear_private() Zi Yan
2026-09-08 2:56 ` [PATCH v3 14/14] mm/page-flags: remove PG_private Zi Yan
4 siblings, 1 reply; 19+ messages in thread
From: Zi Yan @ 2026-09-08 2:56 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, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Matthew Brost, Joshua Hahn, Rakie Kim,
Byungchul Park, linux-fsdevel, linux-trace-kernel
folio_test_fs_private() wraps folio->private != NULL check and excludes
swapcache and hugetlb folios, since swapcache uses swp_entry_t overlapping
with folio->private and hugetlb sets its own flags in folio->private.
Replace open code with the helper, since core MM does this check
frequently.
No functional change intended.
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>
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: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-trace-kernel@vger.kernel.org
---
include/linux/mm.h | 4 +---
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 +--
7 files changed, 29 insertions(+), 20 deletions(-)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 5eb8a62fafb56..c861525cda83f 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3053,9 +3053,7 @@ static inline int folio_expected_ref_count(const struct folio *folio)
* One reference from filesystem private data.
* Use data_race() since folio might not be locked.
*/
- ref_count += data_race(folio_test_private(folio)) &&
- !folio_test_hugetlb(folio) &&
- !folio_test_swapbacked(folio);
+ ref_count += data_race(folio_test_fs_private(folio));
}
/* One reference per page table mapping. */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 9cb4d64739798..ce7fccd90367b 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -1210,6 +1210,28 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
(0xffUL /* order */ | 1UL << PG_has_hwpoisoned | \
1UL << PG_large_rmappable | 1UL << PG_partially_mapped)
+/**
+ * folio_test_fs_private - check if the folio has filesystem private data
+ * @folio: The folio to check.
+ *
+ * Use this in code that may encounter swapcache or hugetlb folios but only
+ * wants to detect filesystem 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.
+ *
+ * Return: true if folio->private is set and the folio is neither swapcache
+ * nor hugetlb.
+ */
+static inline bool folio_test_fs_private(const struct folio *folio)
+{
+ return folio_test_private(folio) && !folio_test_swapbacked(folio) &&
+ !folio_test_hugetlb(folio);
+}
/**
* folio_has_private - Determine if folio has private stuff
* @folio: The folio to be checked
@@ -1219,9 +1241,7 @@ static __always_inline void __ClearPageAnonExclusive(struct page *page)
*/
static inline int folio_has_private(const struct folio *folio)
{
- return (!!folio->private && !folio_test_swapbacked(folio) &&
- !folio_test_hugetlb(folio)) ||
- folio_test_private_2(folio);
+ return folio_test_fs_private(folio) || folio_test_private_2(folio);
}
#undef PF_ANY
diff --git a/include/trace/events/pagemap.h b/include/trace/events/pagemap.h
index 8193f91216822..547a550b81ee1 100644
--- a/include/trace/events/pagemap.h
+++ b/include/trace/events/pagemap.h
@@ -23,9 +23,7 @@
(folio_test_swapbacked(folio) ? PAGEMAP_SWAPBACKED : 0) | \
(folio_test_mappedtodisk(folio) ? PAGEMAP_MAPPEDDISK : 0) | \
/* data_race() is used to read folio->private locklessly */ \
- (data_race(folio_test_private(folio)) && \
- !folio_test_swapbacked(folio) && \
- !folio_test_hugetlb(folio) ? PAGEMAP_BUFFERS : 0) \
+ (data_race(folio_test_fs_private(folio)) ? PAGEMAP_BUFFERS : 0) \
)
TRACE_EVENT(mm_lru_insertion,
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 9b2a9d0794a61..4cb7d9bc47544 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -4833,9 +4833,7 @@ static int split_huge_pages_pid(int pid, unsigned long vaddr_start,
* can be split or not. So skip the check here.
* data_race() is used to read folio->private locklessly.
*/
- if (!(data_race(folio_test_private(folio)) &&
- !folio_test_swapbacked(folio) &&
- !folio_test_hugetlb(folio)) &&
+ if (!data_race(folio_test_fs_private(folio)) &&
folio_expected_ref_count(folio) != folio_ref_count(folio))
goto next;
diff --git a/mm/migrate.c b/mm/migrate.c
index f6befd3ff1c46..2e133d533c8da 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1327,8 +1327,7 @@ 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) && !folio_test_swapbacked(src) &&
- !folio_test_hugetlb(src)) {
+ if (folio_test_fs_private(src)) {
try_to_free_buffers(src);
goto out;
}
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 02ad49b10be07..e7389020d2a56 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -2706,10 +2706,7 @@ bool filemap_dirty_folio(struct address_space *mapping, struct folio *folio)
return false;
/* data_race() is used to read folio->private locklessly */
- __folio_mark_dirty(folio, mapping,
- !(data_race(folio_test_private(folio)) &&
- !folio_test_swapbacked(folio) &&
- !folio_test_hugetlb(folio)));
+ __folio_mark_dirty(folio, mapping, !data_race(folio_test_fs_private(folio)));
if (mapping->host) {
/* !PageAnon && !swapper_space */
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 9348ebf9de882..47352bafc5b6f 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -978,8 +978,7 @@ 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) && !folio_test_swapbacked(folio) &&
- !folio_test_hugetlb(folio)))
+ if (!folio_test_fs_private(folio))
return;
mapping = folio_mapping(folio);
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH v3 10/14] mm/page-flags: introduce folio_test_fs_private()
2026-09-08 2:56 ` [PATCH v3 10/14] mm/page-flags: introduce folio_test_fs_private() Zi Yan
@ 2026-09-08 16:59 ` David Hildenbrand (Arm)
2026-09-08 17:22 ` Zi Yan
0 siblings, 1 reply; 19+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-08 16:59 UTC (permalink / raw)
To: Zi Yan, 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, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Matthew Brost, Joshua Hahn, Rakie Kim,
Byungchul Park, linux-fsdevel, linux-trace-kernel
On 9/8/26 04:56, Zi Yan wrote:
> folio_test_fs_private() wraps folio->private != NULL check and excludes
> swapcache and hugetlb folios, since swapcache uses swp_entry_t overlapping
> with folio->private and hugetlb sets its own flags in folio->private.
> Replace open code with the helper, since core MM does this check
> frequently.
>
> No functional change intended.
>
> 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>
> 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: linux-kernel@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org
> Cc: linux-mm@kvack.org
> Cc: linux-trace-kernel@vger.kernel.org
> ---
> include/linux/mm.h | 4 +---
> 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 +--
> 7 files changed, 29 insertions(+), 20 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 5eb8a62fafb56..c861525cda83f 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -3053,9 +3053,7 @@ static inline int folio_expected_ref_count(const struct folio *folio)
> * One reference from filesystem private data.
> * Use data_race() since folio might not be locked.
> */
> - ref_count += data_race(folio_test_private(folio)) &&
> - !folio_test_hugetlb(folio) &&
> - !folio_test_swapbacked(folio);
> + ref_count += data_race(folio_test_fs_private(folio));
> }
Lol :) That's what I meant with folio_has_attached_private()
(I think I prefer that name as it matches folio_attach_private(), but I might be
biased ;) )
This really should be sqashed into the previous patch, OR, have a prep patch
that only replaces these instances and uses folio_test_private() until you
convert it to folio->private in the second patch.
In short: touch these call sites only once, not twice in a row.
--
Cheers,
David
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v3 10/14] mm/page-flags: introduce folio_test_fs_private()
2026-09-08 16:59 ` David Hildenbrand (Arm)
@ 2026-09-08 17:22 ` Zi Yan
0 siblings, 0 replies; 19+ messages in thread
From: Zi Yan @ 2026-09-08 17:22 UTC (permalink / raw)
To: David Hildenbrand (Arm), 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, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Matthew Brost, Joshua Hahn, Rakie Kim,
Byungchul Park, linux-fsdevel, linux-trace-kernel
On Tue Sep 8, 2026 at 12:59 PM EDT, David Hildenbrand (Arm) wrote:
> On 9/8/26 04:56, Zi Yan wrote:
>> folio_test_fs_private() wraps folio->private != NULL check and excludes
>> swapcache and hugetlb folios, since swapcache uses swp_entry_t overlapping
>> with folio->private and hugetlb sets its own flags in folio->private.
>> Replace open code with the helper, since core MM does this check
>> frequently.
>>
>> No functional change intended.
>>
>> 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>
>> 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: linux-kernel@vger.kernel.org
>> Cc: linux-fsdevel@vger.kernel.org
>> Cc: linux-mm@kvack.org
>> Cc: linux-trace-kernel@vger.kernel.org
>> ---
>> include/linux/mm.h | 4 +---
>> 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 +--
>> 7 files changed, 29 insertions(+), 20 deletions(-)
>>
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index 5eb8a62fafb56..c861525cda83f 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -3053,9 +3053,7 @@ static inline int folio_expected_ref_count(const struct folio *folio)
>> * One reference from filesystem private data.
>> * Use data_race() since folio might not be locked.
>> */
>> - ref_count += data_race(folio_test_private(folio)) &&
>> - !folio_test_hugetlb(folio) &&
>> - !folio_test_swapbacked(folio);
>> + ref_count += data_race(folio_test_fs_private(folio));
>> }
>
> Lol :) That's what I meant with folio_has_attached_private()
>
> (I think I prefer that name as it matches folio_attach_private(), but I might be
> biased ;) )
I can rename it, since it sounds more generic than "fs private".
>
>
> This really should be sqashed into the previous patch, OR, have a prep patch
> that only replaces these instances and uses folio_test_private() until you
> convert it to folio->private in the second patch.
>
> In short: touch these call sites only once, not twice in a row.
Will squash it to the prior patch.
--
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v3 11/14] treewide: remove folio_set/clear_private()
2026-09-08 2:56 [PATCH v3 00/14] Remove PG_private by using page/folio->private checks instead Zi Yan
` (2 preceding siblings ...)
2026-09-08 2:56 ` [PATCH v3 10/14] mm/page-flags: introduce folio_test_fs_private() Zi Yan
@ 2026-09-08 2:56 ` Zi Yan
2026-09-08 17:01 ` David Hildenbrand (Arm)
2026-09-08 2:56 ` [PATCH v3 14/14] mm/page-flags: remove PG_private Zi Yan
4 siblings, 1 reply; 19+ messages in thread
From: Zi Yan @ 2026-09-08 2:56 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, Trond Myklebust, Anna Schumaker,
Jan Kara, Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park,
linux-nfs, linux-fsdevel
They are no-ops now. Remove them.
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5
Signed-off-by: Zi Yan <ziy@nvidia.com>
To: Trond Myklebust <trondmy@kernel.org>
To: Anna Schumaker <anna@kernel.org>
To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
To: Jan Kara <jack@suse.cz>
To: Andrew Morton <akpm@linux-foundation.org>
To: David Hildenbrand <david@kernel.org>
Cc: Zi Yan <ziy@nvidia.com>
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: linux-nfs@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
---
fs/nfs/write.c | 2 --
include/linux/pagemap.h | 4 +---
mm/migrate.c | 1 -
3 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 623e7ef1f73d5..b6967b5286691 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -717,7 +717,6 @@ static void nfs_inode_add_request(struct nfs_page *req)
nfs_lock_request(req);
spin_lock(&mapping->i_private_lock);
set_bit(PG_MAPPED, &req->wb_flags);
- folio_set_private(folio);
folio->private = req;
spin_unlock(&mapping->i_private_lock);
atomic_long_inc(&nfsi->nrequests);
@@ -745,7 +744,6 @@ static void nfs_inode_remove_request(struct nfs_page *req)
spin_lock(&mapping->i_private_lock);
folio->private = NULL;
- folio_clear_private(folio);
clear_bit(PG_MAPPED, &req->wb_head->wb_flags);
spin_unlock(&mapping->i_private_lock);
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 2257df004305e..cc5c2cca814bc 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -594,7 +594,6 @@ static inline void folio_attach_private(struct folio *folio, void *data)
{
folio_get(folio);
folio->private = data;
- folio_set_private(folio);
}
/**
@@ -629,9 +628,8 @@ static inline void *folio_detach_private(struct folio *folio)
{
void *data = folio_get_private(folio);
- if (!folio_test_private(folio))
+ if (!data)
return NULL;
- folio_clear_private(folio);
folio->private = NULL;
folio_put(folio);
diff --git a/mm/migrate.c b/mm/migrate.c
index 2e133d533c8da..77b89d0909f1f 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -835,7 +835,6 @@ void folio_migrate_flags(struct folio *newfolio, struct folio *folio)
*/
if (folio_test_swapcache(folio))
folio_clear_swapcache(folio);
- folio_clear_private(folio);
/* page->private contains hugetlb specific flags */
if (!folio_test_hugetlb(folio))
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH v3 11/14] treewide: remove folio_set/clear_private()
2026-09-08 2:56 ` [PATCH v3 11/14] treewide: remove folio_set/clear_private() Zi Yan
@ 2026-09-08 17:01 ` David Hildenbrand (Arm)
2026-09-08 17:22 ` Zi Yan
0 siblings, 1 reply; 19+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-08 17:01 UTC (permalink / raw)
To: Zi Yan, 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, Trond Myklebust, Anna Schumaker, Jan Kara,
Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, linux-nfs,
linux-fsdevel
On 9/8/26 04:56, Zi Yan wrote:
> They are no-ops now. Remove them.
Subject should likel y say that you remove folio_set/clear_private() *usage*.
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
--
Cheers,
David
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v3 11/14] treewide: remove folio_set/clear_private()
2026-09-08 17:01 ` David Hildenbrand (Arm)
@ 2026-09-08 17:22 ` Zi Yan
0 siblings, 0 replies; 19+ messages in thread
From: Zi Yan @ 2026-09-08 17:22 UTC (permalink / raw)
To: David Hildenbrand (Arm), 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, Trond Myklebust, Anna Schumaker, Jan Kara,
Matthew Brost, Joshua Hahn, Rakie Kim, Byungchul Park, linux-nfs,
linux-fsdevel
On Tue Sep 8, 2026 at 1:01 PM EDT, David Hildenbrand (Arm) wrote:
> On 9/8/26 04:56, Zi Yan wrote:
>> They are no-ops now. Remove them.
>
> Subject should likel y say that you remove folio_set/clear_private() *usage*.
Will adjust it.
>
> Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Thanks.
--
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v3 14/14] mm/page-flags: remove PG_private
2026-09-08 2:56 [PATCH v3 00/14] Remove PG_private by using page/folio->private checks instead Zi Yan
` (3 preceding siblings ...)
2026-09-08 2:56 ` [PATCH v3 11/14] treewide: remove folio_set/clear_private() Zi Yan
@ 2026-09-08 2:56 ` Zi Yan
2026-09-09 14:31 ` David Hildenbrand (Arm)
4 siblings, 1 reply; 19+ messages in thread
From: Zi Yan @ 2026-09-08 2:56 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, Baoquan He, Pasha Tatashin,
Pratyush Yadav, Jonathan Corbet, Jan Kara, Steven Rostedt,
Masami Hiramatsu, Dave Young, Shuah Khan, Mathieu Desnoyers,
kexec, linux-doc, linux-fsdevel, linux-trace-kernel
folio->private != NULL indicates a folio carries private data, replacing
PG_private. All PG_private users are converted. Remove PG_private and
reserve the space as __PG_folio for future use.
__DEF_PAGEFLAG_NAME() is added to show __PG_folio.
Also update files in Documentation. hugetlbfs_reserv.rst is outdated and
left unchanged. It should be rewritten.
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: Baoquan He <baoquan.he@linux.dev>
To: Mike Rapoport <rppt@kernel.org>
To: Pasha Tatashin <pasha.tatashin@soleen.com>
To: Pratyush Yadav <pratyush@kernel.org>
To: Jonathan Corbet <corbet@lwn.net>
To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
To: Jan Kara <jack@suse.cz>
To: David Hildenbrand <david@kernel.org>
To: Steven Rostedt <rostedt@goodmis.org>
To: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Dave Young <ruirui.yang@linux.dev>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: "Liam R. Howlett" <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: kexec@lists.infradead.org
Cc: linux-doc@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: linux-trace-kernel@vger.kernel.org
---
Documentation/admin-guide/kdump/vmcoreinfo.rst | 2 +-
Documentation/filesystems/vfs.rst | 6 +++---
include/linux/page-flags.h | 19 ++-----------------
include/trace/events/mmflags.h | 3 ++-
kernel/vmcore_info.c | 1 -
5 files changed, 8 insertions(+), 23 deletions(-)
diff --git a/Documentation/admin-guide/kdump/vmcoreinfo.rst b/Documentation/admin-guide/kdump/vmcoreinfo.rst
index 7663c610fe901..5f1df6d080508 100644
--- a/Documentation/admin-guide/kdump/vmcoreinfo.rst
+++ b/Documentation/admin-guide/kdump/vmcoreinfo.rst
@@ -325,7 +325,7 @@ NR_FREE_PAGES
On linux-2.6.21 or later, the number of free pages is in
vm_stat[NR_FREE_PAGES]. Used to get the number of free pages.
-PG_lru|PG_private|PG_swapcache|PG_swapbacked|PG_hwpoison|PG_head_mask
+PG_lru|PG_swapcache|PG_swapbacked|PG_hwpoison|PG_head_mask
--------------------------------------------------------------------------
Page attributes. These flags are used to filter various unnecessary for
diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
index d3a93eec3945f..dec7816303c6a 100644
--- a/Documentation/filesystems/vfs.rst
+++ b/Documentation/filesystems/vfs.rst
@@ -649,8 +649,8 @@ Writeback.
The first can be used independently to the others. The VM can try to
release clean pages in order to reuse them. To do this it can call
-->release_folio on clean folios with the private
-flag set. Clean pages without PagePrivate and with no external references
+->release_folio on clean folios with folio->private set. Clean pages
+without folio->private set and with no external references
will be released without notice being given to the address_space.
To achieve this functionality, pages need to be placed on an LRU with
@@ -674,7 +674,7 @@ filemap_fdatawait_range, to wait for all writeback to complete.
An address_space handler may attach extra information to a page,
typically using the 'private' field in the 'struct page'. If such
-information is attached, the PG_Private flag should be set. This will
+information is attached, non-NULL 'private' field will
cause various VM routines to make extra calls into the address_space
handler to deal with that data.
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index ce7fccd90367b..7b7783c0a5216 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -44,10 +44,6 @@
* Consequently, PG_reserved for a page mapped into user space can indicate
* the zero page, the vDSO, MMIO pages or device memory.
*
- * The PG_private bitflag is set on pagecache pages if they contain filesystem
- * specific data (which is normally at page->private). It can be used by
- * private allocations for its own usage.
- *
* During initiation of disk I/O, PG_locked is set. This bit is set before I/O
* and cleared when writeback _starts_ or when read _completes_. PG_writeback
* is set before writeback starts and cleared when it finishes.
@@ -105,7 +101,7 @@ enum pageflags {
PG_owner_2, /* Owner use. If pagecache, fs may use */
PG_arch_1,
PG_reserved,
- PG_private, /* If pagecache, has fs-private data */
+ __PG_folio, /* Do not use: reserved for folio identification */
PG_private_2, /* If pagecache, has fs aux data */
PG_reclaim, /* To be reclaimed asap */
PG_swapbacked, /* Page is backed by RAM/swap */
@@ -576,7 +572,7 @@ FOLIO_FLAG(swapbacked, FOLIO_HEAD_PAGE)
/*
* Private page markings that may be used by the filesystem that owns the page
* for its own purposes.
- * - PG_private and PG_private_2 cause release_folio() and co to be invoked
+ * - folio->private and PG_private_2 cause release_folio() and co to be invoked
*/
static __always_inline bool folio_test_private(const struct folio *folio)
@@ -584,17 +580,6 @@ 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;
-}
-
-/* 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 */
diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h
index ef9aa388b84f7..38a2d30230443 100644
--- a/include/trace/events/mmflags.h
+++ b/include/trace/events/mmflags.h
@@ -130,6 +130,7 @@ TRACE_DEFINE_ENUM(___GFP_LAST_BIT);
#endif
#define DEF_PAGEFLAG_NAME(_name) { 1UL << PG_##_name, __stringify(_name) }
+#define __DEF_PAGEFLAG_NAME(_name) { 1UL << __PG_##_name, __stringify(_name) }
#define __def_pageflag_names \
DEF_PAGEFLAG_NAME(locked), \
@@ -144,7 +145,7 @@ TRACE_DEFINE_ENUM(___GFP_LAST_BIT);
DEF_PAGEFLAG_NAME(owner_2), \
DEF_PAGEFLAG_NAME(arch_1), \
DEF_PAGEFLAG_NAME(reserved), \
- DEF_PAGEFLAG_NAME(private), \
+ __DEF_PAGEFLAG_NAME(folio), \
DEF_PAGEFLAG_NAME(private_2), \
DEF_PAGEFLAG_NAME(writeback), \
DEF_PAGEFLAG_NAME(head), \
diff --git a/kernel/vmcore_info.c b/kernel/vmcore_info.c
index 8614430ca212a..5a417f8a922ab 100644
--- a/kernel/vmcore_info.c
+++ b/kernel/vmcore_info.c
@@ -216,7 +216,6 @@ static int __init crash_save_vmcoreinfo_init(void)
VMCOREINFO_LENGTH(free_area.free_list, MIGRATE_TYPES);
VMCOREINFO_NUMBER(NR_FREE_PAGES);
VMCOREINFO_NUMBER(PG_lru);
- VMCOREINFO_NUMBER(PG_private);
VMCOREINFO_NUMBER(PG_swapcache);
VMCOREINFO_NUMBER(PG_swapbacked);
#define PAGE_SLAB_MAPCOUNT_VALUE (PGTY_slab << 24)
--
2.53.0
^ permalink raw reply related [flat|nested] 19+ messages in thread* Re: [PATCH v3 14/14] mm/page-flags: remove PG_private
2026-09-08 2:56 ` [PATCH v3 14/14] mm/page-flags: remove PG_private Zi Yan
@ 2026-09-09 14:31 ` David Hildenbrand (Arm)
2026-09-09 14:48 ` Zi Yan
0 siblings, 1 reply; 19+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-09 14:31 UTC (permalink / raw)
To: Zi Yan, 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, Baoquan He, Pasha Tatashin,
Pratyush Yadav, Jonathan Corbet, Jan Kara, Steven Rostedt,
Masami Hiramatsu, Dave Young, Shuah Khan, Mathieu Desnoyers,
kexec, linux-doc, linux-fsdevel, linux-trace-kernel
On 9/8/26 04:56, Zi Yan wrote:
> folio->private != NULL indicates a folio carries private data, replacing
> PG_private. All PG_private users are converted. Remove PG_private and
> reserve the space as __PG_folio for future use.
>
> __DEF_PAGEFLAG_NAME() is added to show __PG_folio.
>
> Also update files in Documentation. hugetlbfs_reserv.rst is outdated and
> left unchanged. It should be rewritten.
>
> 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: Baoquan He <baoquan.he@linux.dev>
> To: Mike Rapoport <rppt@kernel.org>
> To: Pasha Tatashin <pasha.tatashin@soleen.com>
> To: Pratyush Yadav <pratyush@kernel.org>
> To: Jonathan Corbet <corbet@lwn.net>
> To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> To: Jan Kara <jack@suse.cz>
> To: David Hildenbrand <david@kernel.org>
> To: Steven Rostedt <rostedt@goodmis.org>
> To: Masami Hiramatsu <mhiramat@kernel.org>
> Cc: Dave Young <ruirui.yang@linux.dev>
> Cc: Shuah Khan <skhan@linuxfoundation.org>
> Cc: Lorenzo Stoakes <ljs@kernel.org>
> Cc: "Liam R. Howlett" <liam@infradead.org>
> Cc: Vlastimil Babka <vbabka@kernel.org>
> Cc: Suren Baghdasaryan <surenb@google.com>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> Cc: kexec@lists.infradead.org
> Cc: linux-doc@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-fsdevel@vger.kernel.org
> Cc: linux-mm@kvack.org
> Cc: linux-trace-kernel@vger.kernel.org
> ---
> Documentation/admin-guide/kdump/vmcoreinfo.rst | 2 +-
> Documentation/filesystems/vfs.rst | 6 +++---
> include/linux/page-flags.h | 19 ++-----------------
> include/trace/events/mmflags.h | 3 ++-
> kernel/vmcore_info.c | 1 -
> 5 files changed, 8 insertions(+), 23 deletions(-)
>
> diff --git a/Documentation/admin-guide/kdump/vmcoreinfo.rst b/Documentation/admin-guide/kdump/vmcoreinfo.rst
> index 7663c610fe901..5f1df6d080508 100644
> --- a/Documentation/admin-guide/kdump/vmcoreinfo.rst
> +++ b/Documentation/admin-guide/kdump/vmcoreinfo.rst
> @@ -325,7 +325,7 @@ NR_FREE_PAGES
> On linux-2.6.21 or later, the number of free pages is in
> vm_stat[NR_FREE_PAGES]. Used to get the number of free pages.
>
> -PG_lru|PG_private|PG_swapcache|PG_swapbacked|PG_hwpoison|PG_head_mask
> +PG_lru|PG_swapcache|PG_swapbacked|PG_hwpoison|PG_head_mask
> --------------------------------------------------------------------------
>
> Page attributes. These flags are used to filter various unnecessary for
> diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
> index d3a93eec3945f..dec7816303c6a 100644
> --- a/Documentation/filesystems/vfs.rst
> +++ b/Documentation/filesystems/vfs.rst
> @@ -649,8 +649,8 @@ Writeback.
>
> The first can be used independently to the others. The VM can try to
> release clean pages in order to reuse them. To do this it can call
> -->release_folio on clean folios with the private
> -flag set. Clean pages without PagePrivate and with no external references
> +->release_folio on clean folios with folio->private set. Clean pages
> +without folio->private set and with no external references
> will be released without notice being given to the address_space.
This reads like it would belong into patch #13?
>
> To achieve this functionality, pages need to be placed on an LRU with
> @@ -674,7 +674,7 @@ filemap_fdatawait_range, to wait for all writeback to complete.
>
> An address_space handler may attach extra information to a page,
> typically using the 'private' field in the 'struct page'. If such
> -information is attached, the PG_Private flag should be set. This will
> +information is attached, non-NULL 'private' field will
Same here?
Likely this could have been restructured to cause less head scratches. I'd
expect any documentation that refers to PG_private to get removed before finally
removing the bit.
Not the end of the world, just a bit confusing while reviewing.
> cause various VM routines to make extra calls into the address_space
> handler to deal with that data.
>
> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
> index ce7fccd90367b..7b7783c0a5216 100644
> --- a/include/linux/page-flags.h
> +++ b/include/linux/page-flags.h
> @@ -44,10 +44,6 @@
> * Consequently, PG_reserved for a page mapped into user space can indicate
> * the zero page, the vDSO, MMIO pages or device memory.
> *
> - * The PG_private bitflag is set on pagecache pages if they contain filesystem
> - * specific data (which is normally at page->private). It can be used by
> - * private allocations for its own usage.
> - *
> * During initiation of disk I/O, PG_locked is set. This bit is set before I/O
> * and cleared when writeback _starts_ or when read _completes_. PG_writeback
> * is set before writeback starts and cleared when it finishes.
> @@ -105,7 +101,7 @@ enum pageflags {
> PG_owner_2, /* Owner use. If pagecache, fs may use */
> PG_arch_1,
> PG_reserved,
> - PG_private, /* If pagecache, has fs-private data */
> + __PG_folio, /* Do not use: reserved for folio identification */
Do we really have to annotate it with __PG_folio ? I'd just keep it simple and
have the comment. That also avoids __DEF_PAGEFLAG_NAME just for this use case.
(sorry if this was discussed in previous review rounds)
--
Cheers,
David
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v3 14/14] mm/page-flags: remove PG_private
2026-09-09 14:31 ` David Hildenbrand (Arm)
@ 2026-09-09 14:48 ` Zi Yan
2026-09-09 14:50 ` David Hildenbrand (Arm)
0 siblings, 1 reply; 19+ messages in thread
From: Zi Yan @ 2026-09-09 14:48 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: 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, linux-mm, linux-kernel,
Baoquan He, Pasha Tatashin, Pratyush Yadav, Jonathan Corbet,
Jan Kara, Steven Rostedt, Masami Hiramatsu, Dave Young,
Shuah Khan, Mathieu Desnoyers, kexec, linux-doc, linux-fsdevel,
linux-trace-kernel
On 9 Sep 2026, at 10:31, David Hildenbrand (Arm) wrote:
> On 9/8/26 04:56, Zi Yan wrote:
>> folio->private != NULL indicates a folio carries private data, replacing
>> PG_private. All PG_private users are converted. Remove PG_private and
>> reserve the space as __PG_folio for future use.
>>
>> __DEF_PAGEFLAG_NAME() is added to show __PG_folio.
>>
>> Also update files in Documentation. hugetlbfs_reserv.rst is outdated and
>> left unchanged. It should be rewritten.
>>
>> 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: Baoquan He <baoquan.he@linux.dev>
>> To: Mike Rapoport <rppt@kernel.org>
>> To: Pasha Tatashin <pasha.tatashin@soleen.com>
>> To: Pratyush Yadav <pratyush@kernel.org>
>> To: Jonathan Corbet <corbet@lwn.net>
>> To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
>> To: Jan Kara <jack@suse.cz>
>> To: David Hildenbrand <david@kernel.org>
>> To: Steven Rostedt <rostedt@goodmis.org>
>> To: Masami Hiramatsu <mhiramat@kernel.org>
>> Cc: Dave Young <ruirui.yang@linux.dev>
>> Cc: Shuah Khan <skhan@linuxfoundation.org>
>> Cc: Lorenzo Stoakes <ljs@kernel.org>
>> Cc: "Liam R. Howlett" <liam@infradead.org>
>> Cc: Vlastimil Babka <vbabka@kernel.org>
>> Cc: Suren Baghdasaryan <surenb@google.com>
>> Cc: Michal Hocko <mhocko@suse.com>
>> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
>> Cc: kexec@lists.infradead.org
>> Cc: linux-doc@vger.kernel.org
>> Cc: linux-kernel@vger.kernel.org
>> Cc: linux-fsdevel@vger.kernel.org
>> Cc: linux-mm@kvack.org
>> Cc: linux-trace-kernel@vger.kernel.org
>> ---
>> Documentation/admin-guide/kdump/vmcoreinfo.rst | 2 +-
>> Documentation/filesystems/vfs.rst | 6 +++---
>> include/linux/page-flags.h | 19 ++-----------------
>> include/trace/events/mmflags.h | 3 ++-
>> kernel/vmcore_info.c | 1 -
>> 5 files changed, 8 insertions(+), 23 deletions(-)
>>
>> diff --git a/Documentation/admin-guide/kdump/vmcoreinfo.rst b/Documentation/admin-guide/kdump/vmcoreinfo.rst
>> index 7663c610fe901..5f1df6d080508 100644
>> --- a/Documentation/admin-guide/kdump/vmcoreinfo.rst
>> +++ b/Documentation/admin-guide/kdump/vmcoreinfo.rst
>> @@ -325,7 +325,7 @@ NR_FREE_PAGES
>> On linux-2.6.21 or later, the number of free pages is in
>> vm_stat[NR_FREE_PAGES]. Used to get the number of free pages.
>>
>> -PG_lru|PG_private|PG_swapcache|PG_swapbacked|PG_hwpoison|PG_head_mask
>> +PG_lru|PG_swapcache|PG_swapbacked|PG_hwpoison|PG_head_mask
>> --------------------------------------------------------------------------
>>
>> Page attributes. These flags are used to filter various unnecessary for
>> diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
>> index d3a93eec3945f..dec7816303c6a 100644
>> --- a/Documentation/filesystems/vfs.rst
>> +++ b/Documentation/filesystems/vfs.rst
>> @@ -649,8 +649,8 @@ Writeback.
>>
>> The first can be used independently to the others. The VM can try to
>> release clean pages in order to reuse them. To do this it can call
>> -->release_folio on clean folios with the private
>> -flag set. Clean pages without PagePrivate and with no external references
>> +->release_folio on clean folios with folio->private set. Clean pages
>> +without folio->private set and with no external references
>> will be released without notice being given to the address_space.
>
> This reads like it would belong into patch #13?
>
>>
>> To achieve this functionality, pages need to be placed on an LRU with
>> @@ -674,7 +674,7 @@ filemap_fdatawait_range, to wait for all writeback to complete.
>>
>> An address_space handler may attach extra information to a page,
>> typically using the 'private' field in the 'struct page'. If such
>> -information is attached, the PG_Private flag should be set. This will
>> +information is attached, non-NULL 'private' field will
>
> Same here?
>
> Likely this could have been restructured to cause less head scratches. I'd
> expect any documentation that refers to PG_private to get removed before finally
> removing the bit.
>
> Not the end of the world, just a bit confusing while reviewing.
Yeah, I will fold the document changes into the corresponding code change patches.
>
>> cause various VM routines to make extra calls into the address_space
>> handler to deal with that data.
>>
>> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
>> index ce7fccd90367b..7b7783c0a5216 100644
>> --- a/include/linux/page-flags.h
>> +++ b/include/linux/page-flags.h
>> @@ -44,10 +44,6 @@
>> * Consequently, PG_reserved for a page mapped into user space can indicate
>> * the zero page, the vDSO, MMIO pages or device memory.
>> *
>> - * The PG_private bitflag is set on pagecache pages if they contain filesystem
>> - * specific data (which is normally at page->private). It can be used by
>> - * private allocations for its own usage.
>> - *
>> * During initiation of disk I/O, PG_locked is set. This bit is set before I/O
>> * and cleared when writeback _starts_ or when read _completes_. PG_writeback
>> * is set before writeback starts and cleared when it finishes.
>> @@ -105,7 +101,7 @@ enum pageflags {
>> PG_owner_2, /* Owner use. If pagecache, fs may use */
>> PG_arch_1,
>> PG_reserved,
>> - PG_private, /* If pagecache, has fs-private data */
>> + __PG_folio, /* Do not use: reserved for folio identification */
>
> Do we really have to annotate it with __PG_folio ? I'd just keep it simple and
> have the comment. That also avoids __DEF_PAGEFLAG_NAME just for this use case.
>
> (sorry if this was discussed in previous review rounds)
No one complained about this yet. :)
I do this because I do not want to change PG_* values after PG_private after
PG_private is removed. And they will be changed back to their original values
when I add PG_folio. That PG_* value churn might be a headache for kdump?
If I add PG_folio the last page flag, it can be a one-time change though.
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v3 14/14] mm/page-flags: remove PG_private
2026-09-09 14:48 ` Zi Yan
@ 2026-09-09 14:50 ` David Hildenbrand (Arm)
2026-09-09 14:51 ` Zi Yan
0 siblings, 1 reply; 19+ messages in thread
From: David Hildenbrand (Arm) @ 2026-09-09 14:50 UTC (permalink / raw)
To: Zi Yan
Cc: 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, linux-mm, linux-kernel,
Baoquan He, Pasha Tatashin, Pratyush Yadav, Jonathan Corbet,
Jan Kara, Steven Rostedt, Masami Hiramatsu, Dave Young,
Shuah Khan, Mathieu Desnoyers, kexec, linux-doc, linux-fsdevel,
linux-trace-kernel
On 9/9/26 16:48, Zi Yan wrote:
> On 9 Sep 2026, at 10:31, David Hildenbrand (Arm) wrote:
>
>> On 9/8/26 04:56, Zi Yan wrote:
>>> folio->private != NULL indicates a folio carries private data, replacing
>>> PG_private. All PG_private users are converted. Remove PG_private and
>>> reserve the space as __PG_folio for future use.
>>>
>>> __DEF_PAGEFLAG_NAME() is added to show __PG_folio.
>>>
>>> Also update files in Documentation. hugetlbfs_reserv.rst is outdated and
>>> left unchanged. It should be rewritten.
>>>
>>> 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: Baoquan He <baoquan.he@linux.dev>
>>> To: Mike Rapoport <rppt@kernel.org>
>>> To: Pasha Tatashin <pasha.tatashin@soleen.com>
>>> To: Pratyush Yadav <pratyush@kernel.org>
>>> To: Jonathan Corbet <corbet@lwn.net>
>>> To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
>>> To: Jan Kara <jack@suse.cz>
>>> To: David Hildenbrand <david@kernel.org>
>>> To: Steven Rostedt <rostedt@goodmis.org>
>>> To: Masami Hiramatsu <mhiramat@kernel.org>
>>> Cc: Dave Young <ruirui.yang@linux.dev>
>>> Cc: Shuah Khan <skhan@linuxfoundation.org>
>>> Cc: Lorenzo Stoakes <ljs@kernel.org>
>>> Cc: "Liam R. Howlett" <liam@infradead.org>
>>> Cc: Vlastimil Babka <vbabka@kernel.org>
>>> Cc: Suren Baghdasaryan <surenb@google.com>
>>> Cc: Michal Hocko <mhocko@suse.com>
>>> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
>>> Cc: kexec@lists.infradead.org
>>> Cc: linux-doc@vger.kernel.org
>>> Cc: linux-kernel@vger.kernel.org
>>> Cc: linux-fsdevel@vger.kernel.org
>>> Cc: linux-mm@kvack.org
>>> Cc: linux-trace-kernel@vger.kernel.org
>>> ---
>>> Documentation/admin-guide/kdump/vmcoreinfo.rst | 2 +-
>>> Documentation/filesystems/vfs.rst | 6 +++---
>>> include/linux/page-flags.h | 19 ++-----------------
>>> include/trace/events/mmflags.h | 3 ++-
>>> kernel/vmcore_info.c | 1 -
>>> 5 files changed, 8 insertions(+), 23 deletions(-)
>>>
>>> diff --git a/Documentation/admin-guide/kdump/vmcoreinfo.rst b/Documentation/admin-guide/kdump/vmcoreinfo.rst
>>> index 7663c610fe901..5f1df6d080508 100644
>>> --- a/Documentation/admin-guide/kdump/vmcoreinfo.rst
>>> +++ b/Documentation/admin-guide/kdump/vmcoreinfo.rst
>>> @@ -325,7 +325,7 @@ NR_FREE_PAGES
>>> On linux-2.6.21 or later, the number of free pages is in
>>> vm_stat[NR_FREE_PAGES]. Used to get the number of free pages.
>>>
>>> -PG_lru|PG_private|PG_swapcache|PG_swapbacked|PG_hwpoison|PG_head_mask
>>> +PG_lru|PG_swapcache|PG_swapbacked|PG_hwpoison|PG_head_mask
>>> --------------------------------------------------------------------------
>>>
>>> Page attributes. These flags are used to filter various unnecessary for
>>> diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
>>> index d3a93eec3945f..dec7816303c6a 100644
>>> --- a/Documentation/filesystems/vfs.rst
>>> +++ b/Documentation/filesystems/vfs.rst
>>> @@ -649,8 +649,8 @@ Writeback.
>>>
>>> The first can be used independently to the others. The VM can try to
>>> release clean pages in order to reuse them. To do this it can call
>>> -->release_folio on clean folios with the private
>>> -flag set. Clean pages without PagePrivate and with no external references
>>> +->release_folio on clean folios with folio->private set. Clean pages
>>> +without folio->private set and with no external references
>>> will be released without notice being given to the address_space.
>>
>> This reads like it would belong into patch #13?
>>
>>>
>>> To achieve this functionality, pages need to be placed on an LRU with
>>> @@ -674,7 +674,7 @@ filemap_fdatawait_range, to wait for all writeback to complete.
>>>
>>> An address_space handler may attach extra information to a page,
>>> typically using the 'private' field in the 'struct page'. If such
>>> -information is attached, the PG_Private flag should be set. This will
>>> +information is attached, non-NULL 'private' field will
>>
>> Same here?
>>
>> Likely this could have been restructured to cause less head scratches. I'd
>> expect any documentation that refers to PG_private to get removed before finally
>> removing the bit.
>>
>> Not the end of the world, just a bit confusing while reviewing.
>
> Yeah, I will fold the document changes into the corresponding code change patches.
>
>>
>>> cause various VM routines to make extra calls into the address_space
>>> handler to deal with that data.
>>>
>>> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
>>> index ce7fccd90367b..7b7783c0a5216 100644
>>> --- a/include/linux/page-flags.h
>>> +++ b/include/linux/page-flags.h
>>> @@ -44,10 +44,6 @@
>>> * Consequently, PG_reserved for a page mapped into user space can indicate
>>> * the zero page, the vDSO, MMIO pages or device memory.
>>> *
>>> - * The PG_private bitflag is set on pagecache pages if they contain filesystem
>>> - * specific data (which is normally at page->private). It can be used by
>>> - * private allocations for its own usage.
>>> - *
>>> * During initiation of disk I/O, PG_locked is set. This bit is set before I/O
>>> * and cleared when writeback _starts_ or when read _completes_. PG_writeback
>>> * is set before writeback starts and cleared when it finishes.
>>> @@ -105,7 +101,7 @@ enum pageflags {
>>> PG_owner_2, /* Owner use. If pagecache, fs may use */
>>> PG_arch_1,
>>> PG_reserved,
>>> - PG_private, /* If pagecache, has fs-private data */
>>> + __PG_folio, /* Do not use: reserved for folio identification */
>>
>> Do we really have to annotate it with __PG_folio ? I'd just keep it simple and
>> have the comment. That also avoids __DEF_PAGEFLAG_NAME just for this use case.
>>
>> (sorry if this was discussed in previous review rounds)
>
> No one complained about this yet. :)
>
> I do this because I do not want to change PG_* values after PG_private after
> PG_private is removed. And they will be changed back to their original values
> when I add PG_folio. That PG_* value churn might be a headache for kdump?
> If I add PG_folio the last page flag, it can be a one-time change though.
Sorry, I meant that you just use
PG_folio, /* Do not use: reserved for folio identification */
Without any further churn. Or is there a problem with this?
--
Cheers,
David
^ permalink raw reply [flat|nested] 19+ messages in thread* Re: [PATCH v3 14/14] mm/page-flags: remove PG_private
2026-09-09 14:50 ` David Hildenbrand (Arm)
@ 2026-09-09 14:51 ` Zi Yan
0 siblings, 0 replies; 19+ messages in thread
From: Zi Yan @ 2026-09-09 14:51 UTC (permalink / raw)
To: David Hildenbrand (Arm)
Cc: 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, linux-mm, linux-kernel,
Baoquan He, Pasha Tatashin, Pratyush Yadav, Jonathan Corbet,
Jan Kara, Steven Rostedt, Masami Hiramatsu, Dave Young,
Shuah Khan, Mathieu Desnoyers, kexec, linux-doc, linux-fsdevel,
linux-trace-kernel
On 9 Sep 2026, at 10:50, David Hildenbrand (Arm) wrote:
> On 9/9/26 16:48, Zi Yan wrote:
>> On 9 Sep 2026, at 10:31, David Hildenbrand (Arm) wrote:
>>
>>> On 9/8/26 04:56, Zi Yan wrote:
>>>> folio->private != NULL indicates a folio carries private data, replacing
>>>> PG_private. All PG_private users are converted. Remove PG_private and
>>>> reserve the space as __PG_folio for future use.
>>>>
>>>> __DEF_PAGEFLAG_NAME() is added to show __PG_folio.
>>>>
>>>> Also update files in Documentation. hugetlbfs_reserv.rst is outdated and
>>>> left unchanged. It should be rewritten.
>>>>
>>>> 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: Baoquan He <baoquan.he@linux.dev>
>>>> To: Mike Rapoport <rppt@kernel.org>
>>>> To: Pasha Tatashin <pasha.tatashin@soleen.com>
>>>> To: Pratyush Yadav <pratyush@kernel.org>
>>>> To: Jonathan Corbet <corbet@lwn.net>
>>>> To: "Matthew Wilcox (Oracle)" <willy@infradead.org>
>>>> To: Jan Kara <jack@suse.cz>
>>>> To: David Hildenbrand <david@kernel.org>
>>>> To: Steven Rostedt <rostedt@goodmis.org>
>>>> To: Masami Hiramatsu <mhiramat@kernel.org>
>>>> Cc: Dave Young <ruirui.yang@linux.dev>
>>>> Cc: Shuah Khan <skhan@linuxfoundation.org>
>>>> Cc: Lorenzo Stoakes <ljs@kernel.org>
>>>> Cc: "Liam R. Howlett" <liam@infradead.org>
>>>> Cc: Vlastimil Babka <vbabka@kernel.org>
>>>> Cc: Suren Baghdasaryan <surenb@google.com>
>>>> Cc: Michal Hocko <mhocko@suse.com>
>>>> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
>>>> Cc: kexec@lists.infradead.org
>>>> Cc: linux-doc@vger.kernel.org
>>>> Cc: linux-kernel@vger.kernel.org
>>>> Cc: linux-fsdevel@vger.kernel.org
>>>> Cc: linux-mm@kvack.org
>>>> Cc: linux-trace-kernel@vger.kernel.org
>>>> ---
>>>> Documentation/admin-guide/kdump/vmcoreinfo.rst | 2 +-
>>>> Documentation/filesystems/vfs.rst | 6 +++---
>>>> include/linux/page-flags.h | 19 ++-----------------
>>>> include/trace/events/mmflags.h | 3 ++-
>>>> kernel/vmcore_info.c | 1 -
>>>> 5 files changed, 8 insertions(+), 23 deletions(-)
>>>>
>>>> diff --git a/Documentation/admin-guide/kdump/vmcoreinfo.rst b/Documentation/admin-guide/kdump/vmcoreinfo.rst
>>>> index 7663c610fe901..5f1df6d080508 100644
>>>> --- a/Documentation/admin-guide/kdump/vmcoreinfo.rst
>>>> +++ b/Documentation/admin-guide/kdump/vmcoreinfo.rst
>>>> @@ -325,7 +325,7 @@ NR_FREE_PAGES
>>>> On linux-2.6.21 or later, the number of free pages is in
>>>> vm_stat[NR_FREE_PAGES]. Used to get the number of free pages.
>>>>
>>>> -PG_lru|PG_private|PG_swapcache|PG_swapbacked|PG_hwpoison|PG_head_mask
>>>> +PG_lru|PG_swapcache|PG_swapbacked|PG_hwpoison|PG_head_mask
>>>> --------------------------------------------------------------------------
>>>>
>>>> Page attributes. These flags are used to filter various unnecessary for
>>>> diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst
>>>> index d3a93eec3945f..dec7816303c6a 100644
>>>> --- a/Documentation/filesystems/vfs.rst
>>>> +++ b/Documentation/filesystems/vfs.rst
>>>> @@ -649,8 +649,8 @@ Writeback.
>>>>
>>>> The first can be used independently to the others. The VM can try to
>>>> release clean pages in order to reuse them. To do this it can call
>>>> -->release_folio on clean folios with the private
>>>> -flag set. Clean pages without PagePrivate and with no external references
>>>> +->release_folio on clean folios with folio->private set. Clean pages
>>>> +without folio->private set and with no external references
>>>> will be released without notice being given to the address_space.
>>>
>>> This reads like it would belong into patch #13?
>>>
>>>>
>>>> To achieve this functionality, pages need to be placed on an LRU with
>>>> @@ -674,7 +674,7 @@ filemap_fdatawait_range, to wait for all writeback to complete.
>>>>
>>>> An address_space handler may attach extra information to a page,
>>>> typically using the 'private' field in the 'struct page'. If such
>>>> -information is attached, the PG_Private flag should be set. This will
>>>> +information is attached, non-NULL 'private' field will
>>>
>>> Same here?
>>>
>>> Likely this could have been restructured to cause less head scratches. I'd
>>> expect any documentation that refers to PG_private to get removed before finally
>>> removing the bit.
>>>
>>> Not the end of the world, just a bit confusing while reviewing.
>>
>> Yeah, I will fold the document changes into the corresponding code change patches.
>>
>>>
>>>> cause various VM routines to make extra calls into the address_space
>>>> handler to deal with that data.
>>>>
>>>> diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
>>>> index ce7fccd90367b..7b7783c0a5216 100644
>>>> --- a/include/linux/page-flags.h
>>>> +++ b/include/linux/page-flags.h
>>>> @@ -44,10 +44,6 @@
>>>> * Consequently, PG_reserved for a page mapped into user space can indicate
>>>> * the zero page, the vDSO, MMIO pages or device memory.
>>>> *
>>>> - * The PG_private bitflag is set on pagecache pages if they contain filesystem
>>>> - * specific data (which is normally at page->private). It can be used by
>>>> - * private allocations for its own usage.
>>>> - *
>>>> * During initiation of disk I/O, PG_locked is set. This bit is set before I/O
>>>> * and cleared when writeback _starts_ or when read _completes_. PG_writeback
>>>> * is set before writeback starts and cleared when it finishes.
>>>> @@ -105,7 +101,7 @@ enum pageflags {
>>>> PG_owner_2, /* Owner use. If pagecache, fs may use */
>>>> PG_arch_1,
>>>> PG_reserved,
>>>> - PG_private, /* If pagecache, has fs-private data */
>>>> + __PG_folio, /* Do not use: reserved for folio identification */
>>>
>>> Do we really have to annotate it with __PG_folio ? I'd just keep it simple and
>>> have the comment. That also avoids __DEF_PAGEFLAG_NAME just for this use case.
>>>
>>> (sorry if this was discussed in previous review rounds)
>>
>> No one complained about this yet. :)
>>
>> I do this because I do not want to change PG_* values after PG_private after
>> PG_private is removed. And they will be changed back to their original values
>> when I add PG_folio. That PG_* value churn might be a headache for kdump?
>> If I add PG_folio the last page flag, it can be a one-time change though.
>
> Sorry, I meant that you just use
>
> PG_folio, /* Do not use: reserved for folio identification */
>
> Without any further churn. Or is there a problem with this?
Probably not. Let me do that.
Best Regards,
Yan, Zi
^ permalink raw reply [flat|nested] 19+ messages in thread