From: sashiko-bot@kernel.org
To: "Kiryl Shutsemau (Meta)" <kas@kernel.org>,
"Andrew Morton" <akpm@linux-foundation.org>,
"Linus Torvalds" <torvalds@linux-foundation.org>,
"David Hildenbrand" <david@kernel.org>,
"Matthew Wilcox" <willy@infradead.org>,
"Vlastimil Babka" <vbabka@kernel.org>,
"Lorenzo Stoakes" <ljs@kernel.org>, "Jan Kara" <jack@suse.cz>,
"Hugh Dickins" <hughd@google.com>,
"Christian Brauner" <brauner@kernel.org>,
"Alexander Viro" <viro@zeniv.linux.org.uk>,
"Harry Yoo" <harry@kernel.org>
Cc: "Miklos Szeredi" <miklos@szeredi.hu>,
"Miaohe Lin" <linmiaohe@huawei.com>,
"Naoya Horiguchi" <nao.horiguchi@gmail.com>,
"Oscar Salvador" <osalvador@suse.de>,
"Liam R. Howlett" <liam@infradead.org>,
"Mike Rapoport" <rppt@kernel.org>,
"Suren Baghdasaryan" <surenb@google.com>,
"Michal Hocko" <mhocko@suse.com>,
"Brendan Jackman" <brendan.jackman@linux.dev>,
"Johannes Weiner" <hannes@cmpxchg.org>, "Zi Yan" <ziy@nvidia.com>,
"Baolin Wang" <baolin.wang@linux.alibaba.com>,
"Nico Pache" <nico.pache@linux.dev>,
"Ryan Roberts" <ryan.roberts@arm.com>,
"Dev Jain" <dev.jain@arm.com>, "Barry Song" <baohua@kernel.org>,
"Lance Yang" <lance.yang@linux.dev>,
"Usama Arif" <usama.arif@linux.dev>,
"Kairui Song" <kasong@tencent.com>,
"Qi Zheng" <qi.zheng@linux.dev>,
"Shakeel Butt" <shakeel.butt@linux.dev>,
"Axel Rasmussen" <axelrasmussen@google.com>,
"Yuanchu Xie" <yuanchu@google.com>, "Wei Xu" <weixugc@google.com>,
"Baoquan He" <baoquan.he@linux.dev>,
"Paul E. McKenney" <paulmck@kernel.org>,
"Pedro Falcato" <pfalcato@suse.de>,
"Luis Chamberlain" <mcgrof@kernel.org>,
"Ilya Gladyshev" <ilya.gladyshev@linux.dev>,
"Jaegeuk Kim" <jaegeuk@kernel.org>,
linux-mm@kvack.org, kernel-team@meta.com
Subject: Re: [RFC PATCH v2 17/18] mm/shmem: read without folio references
Date: Thu, 05 Nov 2026 13:03:46 +0000 [thread overview]
Message-ID: <sashiko-outbox-199110@kernel.org> (raw)
In-Reply-To: <20261104130118.2507513-18-kas@kernel.org>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] mm: race in filemap_read_rcu_can_copy() copies hwpoisoned tail pages on split
--
commit 6b69ad4da5a3278d80ff53e3999062ede8b8a468
Author: Kiryl Shutsemau (Meta) <kas@kernel.org>
mm/shmem: read without folio references
This commit updates shmem_file_read_iter() to copy from the page cache
without taking folio references or locks via filemap_read_rcu() before
falling back to the slow path. It also updates filemap_read_rcu_can_copy()
to ignore PG_readahead on swapbacked folios where that bit is PG_reclaim.
> diff --git a/mm/shmem.c b/mm/shmem.c
> index 1c700fa9666d0..8700b03a8a5ee 100644
> --- a/mm/shmem.c
> +++ b/mm/shmem.c
> @@ -3313,7 +3313,14 @@ static ssize_t shmem_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
> pgoff_t index;
> unsigned long offset;
> int error = 0;
> - ssize_t retval = 0;
> + ssize_t retval;
> +
> + retval = filemap_read_rcu(iocb, to, last_pos);
> + if (retval) {
> + last_pos = iocb->ki_pos;
> + if (!iov_iter_count(to))
> + goto out;
> + }
[Severity: High]
Can calling filemap_read_rcu() from shmem_file_read_iter() copy from a
hwpoisoned tail page instead of returning -EIO when a large shmem folio is
concurrently split?
Unlike regular filesystems, shmem_error_remove_folio() keeps hwpoisoned
folios in the page cache. When a large folio has a hwpoisoned tail page
(index > folio->index), PG_hwpoison is set on that tail subpage and
PG_has_hwpoisoned is set on the folio. If the folio is later split (for
example via truncate_inode_partial_folio(), shmem_unused_huge_shrink(), or
shmem_writeout(), or during memory_failure()), a concurrent reader in
shmem_file_read_iter() -> filemap_read_rcu() -> filemap_read_rcu_batch() can
bypass the hwpoison checks in three ways:
1. In mm/huge_memory.c:__split_folio_to_order(), PG_has_hwpoisoned is cleared
on the folio at the beginning of the split, before the loop over the subpages,
before ClearPageCompound() clears PG_head, and before
__folio_freeze_and_split_unmapped() updates the XArray slots:
mm/huge_memory.c:__split_folio_to_order() {
...
folio_clear_has_hwpoisoned(folio);
/* Check first new_nr_pages since the loop below skips them */
if (handle_hwpoison &&
page_range_has_hwpoisoned(folio_page(folio, 0), new_nr_pages))
folio_set_has_hwpoisoned(folio);
...
if (new_order)
folio_set_order(folio, new_order);
else
ClearPageCompound(&folio->page);
}
During this window (or after a non-uniform split where new_order > 0 leaves
PG_head set on the first half while the poisoned subpage is in the second
half, before the XArray slots are updated), xas_load() still returns the
original folio with PG_head set and PG_has_hwpoisoned clear. In
filemap_read_rcu_can_copy(), folio_test_hwpoison(folio) only checks the head
page, so it returns true for the poisoned tail page, and
filemap_read_rcu_size() also sees xas_load(xas) == folio at end - 1, allowing
filemap_read_rcu_copy() to copy across the poisoned subpage.
2. In mm/filemap.c:filemap_read_rcu_can_copy(), folio_test_large(folio) is
tested twice without synchronization:
mm/filemap.c:filemap_read_rcu_can_copy() {
...
/* A split clears PG_head before it puts the new folios in their slots */
if (!folio_test_large(folio) && folio->index != index)
return false;
/* memory_failure() waits only for readers that got past this */
if (folio_test_hwpoison(folio))
return false;
/* Not folio_test_has_hwpoisoned(): it asserts PG_head, a split clears it */
if (folio_test_large(folio) &&
test_bit(PG_has_hwpoisoned, &folio->_flags_1))
return false;
...
}
If ClearPageCompound(&folio->page) runs between those two checks, the first
folio_test_large(folio) sees true (allowing folio->index != index) and the
second sees false (skipping the PG_has_hwpoisoned check).
3. Neither filemap_read_rcu_can_copy() nor filemap_read_rcu_copy() checks
PageHWPoison(page) on the individual subpages being copied:
mm/filemap.c:filemap_read_rcu_copy() {
struct page *page = folio_page(folio, index - folio->index);
size_t n = 0;
while (n < bytes) {
size_t len = min(bytes - n, PAGE_SIZE - offset);
size_t done;
void *kaddr;
kaddr = kmap_local_page(page);
done = _copy_to_iter(kaddr + offset, len, iter);
...
}
Could this copy corrupted data to userspace or trigger an unhandled kernel
machine check or page fault if the poisoned page was unmapped from the direct
map?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261104130118.2507513-1-kas@kernel.org?part=17
next prev parent reply other threads:[~2026-11-05 13:04 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 13:00 [RFC PATCH v2 00/18] mm: read the page cache without folio references Kiryl Shutsemau (Meta)
2026-11-04 13:00 ` [RFC PATCH v2 01/18] mm: free PG_rcu_free folios only after an RCU grace period Kiryl Shutsemau (Meta)
2026-11-05 20:37 ` David Hildenbrand (Arm)
2026-11-04 13:00 ` [RFC PATCH v2 02/18] splice: don't steal page cache folios Kiryl Shutsemau (Meta)
2026-11-04 16:05 ` David Hildenbrand (Arm)
2026-11-05 14:55 ` Kiryl Shutsemau
2026-11-04 13:00 ` [RFC PATCH v2 03/18] fuse: don't move a folio with PG_rcu_free into a fuse file Kiryl Shutsemau (Meta)
2026-11-04 13:01 ` [RFC PATCH v2 04/18] mm: count the pages waiting for a grace period Kiryl Shutsemau (Meta)
2026-11-04 13:01 ` [RFC PATCH v2 05/18] mm: expedite the grace period when a CPU has many deferred frees Kiryl Shutsemau (Meta)
2026-11-04 13:01 ` [RFC PATCH v2 06/18] mm: free the pages waiting for a grace period before OOM Kiryl Shutsemau (Meta)
2026-11-05 13:03 ` sashiko-bot
2026-11-04 13:01 ` [RFC PATCH v2 07/18] mm: free the pages waiting for a grace period before isolation fails Kiryl Shutsemau (Meta)
2026-11-05 13:03 ` sashiko-bot
2026-11-04 13:01 ` [RFC PATCH v2 08/18] mm/compaction: free the migrated folios that wait for a grace period Kiryl Shutsemau (Meta)
2026-11-05 13:03 ` sashiko-bot
2026-11-04 13:01 ` [RFC PATCH v2 09/18] mm/memory-failure: handle folios with PG_rcu_free Kiryl Shutsemau (Meta)
2026-11-05 13:03 ` sashiko-bot
2026-11-04 13:01 ` [RFC PATCH v2 10/18] mm: have folio_mark_accessed() return whether the folio is hot Kiryl Shutsemau (Meta)
2026-11-04 13:01 ` [RFC PATCH v2 11/18] mm/filemap: mark a folio accessed in one place in filemap_read() Kiryl Shutsemau (Meta)
2026-11-04 13:01 ` [RFC PATCH v2 12/18] mm/filemap: set PG_rcu_free on the folios that reads keep coming back to Kiryl Shutsemau (Meta)
2026-11-04 13:01 ` [RFC PATCH v2 13/18] mm/filemap: read from the page cache without folio references Kiryl Shutsemau (Meta)
2026-11-04 13:01 ` [RFC PATCH v2 14/18] mm/filemap: read large folios " Kiryl Shutsemau (Meta)
2026-11-05 13:03 ` sashiko-bot
2026-11-04 13:01 ` [RFC PATCH v2 15/18] mm/filemap: don't store f_ra.prev_pos for FMODE_RANDOM files Kiryl Shutsemau (Meta)
2026-11-04 13:01 ` [RFC PATCH v2 16/18] mm/shmem: count accesses to a folio the way filemap_read() does Kiryl Shutsemau (Meta)
2026-11-04 13:01 ` [RFC PATCH v2 17/18] mm/shmem: read without folio references Kiryl Shutsemau (Meta)
2026-11-05 13:03 ` sashiko-bot [this message]
2026-11-04 13:01 ` [RFC PATCH v2 18/18] mm/filemap: add a debugfs switch for lockless page cache reads Kiryl Shutsemau (Meta)
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=sashiko-outbox-199110@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=axelrasmussen@google.com \
--cc=baohua@kernel.org \
--cc=baolin.wang@linux.alibaba.com \
--cc=baoquan.he@linux.dev \
--cc=brauner@kernel.org \
--cc=brendan.jackman@linux.dev \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=hannes@cmpxchg.org \
--cc=harry@kernel.org \
--cc=hughd@google.com \
--cc=ilya.gladyshev@linux.dev \
--cc=jack@suse.cz \
--cc=jaegeuk@kernel.org \
--cc=kas@kernel.org \
--cc=kasong@tencent.com \
--cc=kernel-team@meta.com \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linmiaohe@huawei.com \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mcgrof@kernel.org \
--cc=mhocko@suse.com \
--cc=miklos@szeredi.hu \
--cc=nao.horiguchi@gmail.com \
--cc=nico.pache@linux.dev \
--cc=osalvador@suse.de \
--cc=paulmck@kernel.org \
--cc=pfalcato@suse.de \
--cc=qi.zheng@linux.dev \
--cc=rppt@kernel.org \
--cc=ryan.roberts@arm.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=shakeel.butt@linux.dev \
--cc=surenb@google.com \
--cc=torvalds@linux-foundation.org \
--cc=usama.arif@linux.dev \
--cc=vbabka@kernel.org \
--cc=viro@zeniv.linux.org.uk \
--cc=weixugc@google.com \
--cc=willy@infradead.org \
--cc=yuanchu@google.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.