From: Usama Arif <usama.arif@linux.dev>
To: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>,
"David Hildenbrand" <david@kernel.org>,
"Liam R. Howlett" <liam@infradead.org>,
"Vlastimil Babka" <vbabka@kernel.org>,
"Mike Rapoport" <rppt@kernel.org>,
"Suren Baghdasaryan" <surenb@google.com>,
"Michal Hocko" <mhocko@suse.com>,
"David Rientjes" <rientjes@google.com>,
"Shakeel Butt" <shakeel.butt@linux.dev>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Jann Horn" <jannh@google.com>,
"Pedro Falcato" <pfalcato@suse.de>,
"Matthew Wilcox (Oracle)" <willy@infradead.org>,
"Jan Kara" <jack@suse.cz>, "Nhat Pham" <nphamcs@gmail.com>,
"Johannes Weiner" <hannes@cmpxchg.org>, "Zi Yan" <ziy@nvidia.com>,
"Matthew Brost" <matthew.brost@intel.com>,
"Joshua Hahn" <joshua.hahnjy@gmail.com>,
"Byungchul Park" <byungchul@sk.com>,
"Gregory Price" <gourry@gourry.net>,
"Ying Huang" <ying.huang@linux.alibaba.com>,
"Alistair Popple" <apopple@nvidia.com>,
"Kairui Song" <kasong@tencent.com>,
"Balbir Singh" <balbirs@nvidia.com>,
"Jérôme Glisse" <jglisse@redhat.com>,
"Kiryl Shutsemau" <kas@kernel.org>,
"Yu-cheng Yu" <yu-cheng.yu@intel.com>,
"Dave Hansen" <dave.hansen@linux.intel.com>,
"Dennis Zhou" <dennis@kernel.org>, "Tejun Heo" <tj@kernel.org>,
"Christoph Lameter" <cl@gentwo.org>,
"Peng Fan" <peng.fan@nxp.com>, "Josef Bacik" <jbacik@fb.com>,
"Chris Mason" <mason@kernel.org>
Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org,
linux-fsdevel@vger.kernel.org,
"Borislav Petkov (AMD)" <bp@alien8.de>,
Mark Brown <broonie@kernel.org>,
"Dennis Zhou (Facebook)" <dennisszhou@gmail.com>,
Rick Edgecombe <rick.p.edgecombe@intel.com>,
stable@vger.kernel.org
Subject: Re: [PATCH 02/13] mm: cachestat: count each page only once
Date: Wed, 11 Nov 2026 23:26:38 +0000 [thread overview]
Message-ID: <5586b128-4402-4fb4-a535-f3766d807042@linux.dev> (raw)
In-Reply-To: <20261111-mason-migrate-et-al-fixes-v1-2-3d2454362e8d@kernel.org>
On 11/11/2026 18:13, Lorenzo Stoakes (ARM) wrote:
> From: Chris Mason <mason@kernel.org>
>
> It turns out that filemap_cachestat() can unwittingly return incorrect
> page counts, if large folios are present.
>
> This can occur due to underflow - nr_cache is nearly 2^64 on a 64-bit
> kernel if the input range starts more than 64 pages into a folio that is
> split during the call.
>
> It can also occur due to pages after a large folio being skipped if the
> range starts in its second or later XArray slot and the call reschedules at
> that folio.
>
> Finally it can be caused by pages being counted twice due to folios in the
> range being split or collapsed during the call.
>
> filemap_cachestat() walks the page cache under the RCU read lock only,
> and for each entry it counts the pages that lie in the range. It does
> not track how far it has counted, so the counts are only right if the
> walk returns each index once.
>
> But a large folio can be split during the walk, or small folios can be
> collapsed into a large one, and the next entries then cover indices that
> were already counted.
>
> Resolve the issue by tracking the current index as one past the last index
> in the folio, and explicitly using xas_set() to set the current position in
> the XArray.
>
> Additionally, add a check for folio_last_index reaching or exceeding
> last_index and break out of the loop if so.
>
> Fixes: cf264e1329fb ("cachestat: implement cachestat syscall")
> Cc: <stable@vger.kernel.org>
> Signed-off-by: Chris Mason <mason@kernel.org>
> [ ljs: updated to use curr_index, fixed comments, updated commit message ]
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
First time I have looked at cachestat, but it makes sense. Tracking curr_index
makes cachestat skip already counted entries, preventing duplicate counts
during folio splits or collapses.
Acked-by: Usama Arif <usama.arif@linux.dev>
> mm/filemap.c | 16 +++++++++++++---
> 1 file changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/mm/filemap.c b/mm/filemap.c
> index b04be64a5069..7c05e4fad081 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -4638,6 +4638,7 @@ static void filemap_cachestat(struct address_space *mapping,
> {
> XA_STATE(xas, &mapping->i_pages, first_index);
> struct folio *folio;
> + pgoff_t curr_index = first_index;
>
> /* Flush stats (and potentially sleep) outside the RCU read section. */
> mem_cgroup_flush_stats_ratelimited(NULL);
> @@ -4667,13 +4668,19 @@ static void filemap_cachestat(struct address_space *mapping,
> folio_first_index = round_down(xas.xa_index, 1 << order);
> folio_last_index = folio_first_index + nr_pages - 1;
>
> + /* Skip already counted entries, e.g. after a split/collapse. */
> + if (folio_last_index < curr_index)
> + goto resched;
> +
> /* Folios might straddle the range boundaries, only count covered pages */
> - if (folio_first_index < first_index)
> - nr_pages -= first_index - folio_first_index;
> + if (folio_first_index < curr_index)
> + nr_pages -= curr_index - folio_first_index;
>
> if (folio_last_index > last_index)
> nr_pages -= folio_last_index - last_index;
>
> + curr_index = folio_last_index + 1;
> +
> if (xa_is_value(folio)) {
> /* page is evicted */
> void *shadow = (void *)folio;
> @@ -4721,8 +4728,11 @@ static void filemap_cachestat(struct address_space *mapping,
> cs->nr_writeback += nr_pages;
>
> resched:
> + if (folio_last_index >= last_index)
> + break;
> +
> if (need_resched()) {
> - xas_pause(&xas);
> + xas_set(&xas, curr_index);
> cond_resched_rcu();
> }
> }
>
next prev parent reply other threads:[~2026-11-11 23:26 UTC|newest]
Thread overview: 70+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-11 18:13 [PATCH 00/13] mm: batch of (urgentish?) fixes in oomk, cachestat, dev-migrate, percpu Lorenzo Stoakes (ARM)
2026-11-11 18:13 ` [PATCH 01/13] mm/mmap: free gathered pages before MMF_OOM_SKIP Lorenzo Stoakes (ARM)
2026-11-11 22:49 ` Usama Arif
2026-11-12 12:18 ` Lorenzo Stoakes (ARM)
2026-11-12 11:21 ` Pedro Falcato
2026-11-12 12:17 ` Lorenzo Stoakes (ARM)
2026-11-12 12:18 ` Lorenzo Stoakes (ARM)
2026-11-12 12:28 ` Pedro Falcato
2026-11-12 12:33 ` Lorenzo Stoakes (ARM)
2026-11-12 11:43 ` Michal Hocko
2026-11-12 12:14 ` Lorenzo Stoakes (ARM)
2026-11-12 12:48 ` Michal Hocko
2026-11-12 14:12 ` Michal Hocko
2026-11-12 14:27 ` Lorenzo Stoakes (ARM)
2026-11-12 16:59 ` Gregory Price (Meta)
2026-11-12 19:15 ` Lorenzo Stoakes (ARM)
2026-11-11 18:13 ` [PATCH 02/13] mm: cachestat: count each page only once Lorenzo Stoakes (ARM)
2026-11-11 23:26 ` Usama Arif [this message]
2026-11-12 11:27 ` Pedro Falcato
2026-11-12 13:30 ` Nhat Pham
2026-11-12 16:13 ` Johannes Weiner
2026-11-12 16:37 ` Gregory Price (Meta)
2026-11-11 18:13 ` [PATCH 03/13] mm: cachestat: restart the walk after each entry Lorenzo Stoakes (ARM)
2026-11-11 23:38 ` Usama Arif
2026-11-12 12:22 ` Lorenzo Stoakes (ARM)
2026-11-12 11:29 ` Pedro Falcato
2026-11-12 12:33 ` Nhat Pham
2026-11-12 16:15 ` Johannes Weiner
2026-11-12 16:40 ` Gregory Price (Meta)
2026-11-11 18:13 ` [PATCH 04/13] mm/migrate_device: allocate THP deferred split heads Lorenzo Stoakes (ARM)
2026-11-11 19:30 ` Kiryl Shutsemau
2026-11-11 19:40 ` David Hildenbrand (Arm)
2026-11-11 22:18 ` Andrew Morton
2026-11-11 23:02 ` Balbir Singh
2026-11-12 17:07 ` Gregory Price (Meta)
2026-11-12 18:16 ` sashiko-bot
2026-11-11 18:13 ` [PATCH 05/13] mm/migrate_device: don't collect a range twice Lorenzo Stoakes (ARM)
2026-11-12 17:15 ` Gregory Price (Meta)
2026-11-12 18:16 ` sashiko-bot
2026-11-11 18:13 ` [PATCH 06/13] mm/migrate_device: don't let go of the fault page Lorenzo Stoakes (ARM)
2026-11-12 17:56 ` Gregory Price (Meta)
2026-11-11 18:13 ` [PATCH 07/13] mm/migrate_device: look up fault folio after a split Lorenzo Stoakes (ARM)
2026-11-12 17:35 ` Gregory Price (Meta)
2026-11-12 19:12 ` Lorenzo Stoakes (ARM)
2026-11-11 18:13 ` [PATCH 08/13] mm/migrate_device: fix ksmd oops on a migrated KSM page Lorenzo Stoakes (ARM)
2026-11-11 21:54 ` David Hildenbrand (Arm)
2026-11-11 22:47 ` Alistair Popple
2026-11-11 23:27 ` Balbir Singh
2026-11-12 17:22 ` Gregory Price (Meta)
2026-11-12 18:16 ` sashiko-bot
2026-11-11 18:13 ` [PATCH 09/13] mm/migrate_device: fix use-after-free of the anon rmap Lorenzo Stoakes (ARM)
2026-11-11 23:04 ` Alistair Popple
2026-11-12 19:05 ` Lorenzo Stoakes (ARM)
2026-11-12 18:11 ` Gregory Price (Meta)
2026-11-12 19:10 ` Lorenzo Stoakes (ARM)
2026-11-12 18:16 ` sashiko-bot
2026-11-11 18:13 ` [PATCH 10/13] mm/migrate_device: refuse to migrate shadow stacks Lorenzo Stoakes (ARM)
2026-11-11 21:15 ` Balbir Singh
2026-11-11 23:15 ` Alistair Popple
2026-11-12 18:16 ` sashiko-bot
2026-11-12 19:03 ` Lorenzo Stoakes (ARM)
2026-11-12 22:53 ` Roman Gushchin
2026-11-13 0:22 ` Roman Gushchin
2026-11-11 18:13 ` [PATCH 11/13] percpu: fix contig hints that are too low Lorenzo Stoakes (ARM)
2026-11-12 18:30 ` Gregory Price (Meta)
2026-11-11 18:13 ` [PATCH 12/13] percpu: search the whole reserved chunk Lorenzo Stoakes (ARM)
2026-11-12 18:33 ` Gregory Price (Meta)
2026-11-11 18:13 ` [PATCH 13/13] percpu: queue the balance work on an unbound workqueue Lorenzo Stoakes (ARM)
2026-11-12 18:41 ` Gregory Price (Meta)
2026-11-12 18:45 ` Lorenzo Stoakes (ARM)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5586b128-4402-4fb4-a535-f3766d807042@linux.dev \
--to=usama.arif@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=apopple@nvidia.com \
--cc=balbirs@nvidia.com \
--cc=bp@alien8.de \
--cc=broonie@kernel.org \
--cc=byungchul@sk.com \
--cc=cl@gentwo.org \
--cc=dave.hansen@linux.intel.com \
--cc=david@kernel.org \
--cc=dennis@kernel.org \
--cc=dennisszhou@gmail.com \
--cc=gourry@gourry.net \
--cc=hannes@cmpxchg.org \
--cc=jack@suse.cz \
--cc=jannh@google.com \
--cc=jbacik@fb.com \
--cc=jglisse@redhat.com \
--cc=joshua.hahnjy@gmail.com \
--cc=kas@kernel.org \
--cc=kasong@tencent.com \
--cc=liam@infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mason@kernel.org \
--cc=matthew.brost@intel.com \
--cc=mhocko@suse.com \
--cc=nphamcs@gmail.com \
--cc=peng.fan@nxp.com \
--cc=pfalcato@suse.de \
--cc=rick.p.edgecombe@intel.com \
--cc=rientjes@google.com \
--cc=rppt@kernel.org \
--cc=shakeel.butt@linux.dev \
--cc=stable@vger.kernel.org \
--cc=surenb@google.com \
--cc=tj@kernel.org \
--cc=vbabka@kernel.org \
--cc=willy@infradead.org \
--cc=ying.huang@linux.alibaba.com \
--cc=yu-cheng.yu@intel.com \
--cc=ziy@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.