From: Baolin Wang <baolin.wang@linux.alibaba.com>
To: Chi Zhiling <chizhiling@163.com>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
linux-fsdevel@vger.kernel.org
Cc: Hugh Dickins <hughd@google.com>,
"Matthew Wilcox (Oracle)" <willy@infradead.org>,
Jan Kara <jack@suse.cz>,
Andrew Morton <akpm@linux-foundation.org>,
David Hildenbrand <david@kernel.org>,
Lorenzo Stoakes <ljs@kernel.org>, Zi Yan <ziy@nvidia.com>,
"Liam R. Howlett" <liam@infradead.org>,
Nico Pache <npache@redhat.com>,
Ryan Roberts <ryan.roberts@arm.com>, Dev Jain <dev.jain@arm.com>,
Barry Song <baohua@kernel.org>, Lance Yang <lance.yang@linux.dev>,
Chi Zhiling <chizhiling@kylinos.cn>
Subject: Re: [PATCH v1 5/5] mm/shmem: optimize file read with folio batching
Date: Tue, 26 May 2026 11:11:38 +0800 [thread overview]
Message-ID: <6881f92c-972a-4b7a-b3c0-93a91ff38b88@linux.alibaba.com> (raw)
In-Reply-To: <1fd099de-97d9-4a54-a97f-062fbae1d88e@163.com>
On 5/25/26 5:47 PM, Chi Zhiling wrote:
> On 5/25/26 4:37 PM, Baolin Wang wrote:
>>
>>
>> On 5/20/26 6:15 PM, Chi Zhiling wrote:
>>> From: Chi Zhiling <chizhiling@kylinos.cn>
>>>
>>> Optimize shmem file read by using filemap_get_folios_contig() to
>>> batch fetch contiguous folios from the page cache, reducing the
>>> overhead of repeated shmem_get_folio() calls.
>>>
>>> When the folio batch is exhausted, attempt to refill it with
>>> filemap_get_folios_contig(). If no folios are found (hole or swapped
>>> out pages), fall back to shmem_get_folio() to handle these cases
>>> individually.
>>>
>>> Additionally:
>>> - Defer folio_put() until the batch is exhausted or on exit
>>> - Add folio_test_uptodate() check before copying to ensure data
>>> validity
>>>
>>> Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn>
>>> ---
>>> mm/shmem.c | 50 ++++++++++++++++++++++++++++++++++++--------------
>>> 1 file changed, 36 insertions(+), 14 deletions(-)
>>>
>>> diff --git a/mm/shmem.c b/mm/shmem.c
>>> index 96ea5a4c0aff..e0eacc23cccd 100644
>>> --- a/mm/shmem.c
>>> +++ b/mm/shmem.c
>>> @@ -3355,11 +3355,14 @@ static ssize_t shmem_file_read_iter(struct
>>> kiocb *iocb, struct iov_iter *to)
>>> struct file *file = iocb->ki_filp;
>>> struct inode *inode = file_inode(file);
>>> struct address_space *mapping = inode->i_mapping;
>>> + struct folio_batch fbatch;
>>> pgoff_t index;
>>> unsigned long offset;
>>> int error = 0;
>>> ssize_t retval = 0;
>>> + folio_batch_init(&fbatch);
>>> +
>>> for (;;) {
>>> struct folio *folio = NULL;
>>> struct page *page = NULL;
>>> @@ -3372,18 +3375,38 @@ static ssize_t shmem_file_read_iter(struct
>>> kiocb *iocb, struct iov_iter *to)
>>> break;
>>> index = iocb->ki_pos >> PAGE_SHIFT;
>>> - error = shmem_get_folio(inode, index, 0, &folio, SGP_READ);
>>> - if (error) {
>>> - if (error == -EINVAL)
>>> - error = 0;
>>> - break;
>>> +fetch:
>>> + folio = folio_batch_next(&fbatch);
>>> + if (!folio) {
>>> + pgoff_t start = index;
>>> + pgoff_t end = (iocb->ki_pos + to->count - 1) >> PAGE_SHIFT;
>>> +
>>> + if (folio_batch_count(&fbatch)) {
>>> + for (int i = 0; i < folio_batch_count(&fbatch); i++)
>>> + folio_put(fbatch.folios[i]);
>>> + folio_batch_reinit(&fbatch);
>>> + }
>>> +
>>> + filemap_get_folios_contig(inode->i_mapping, &start, end,
>>> &fbatch);
>>> + if (folio_batch_count(&fbatch))
>>> + goto fetch;
>>> +
>>> + error = shmem_get_folio(inode, index, 0, &folio, SGP_READ);
>>> + if (unlikely(error)) {
>>> + if (error == -EINVAL)
>>> + error = 0;
>>> + break;
>>> + }
>>> + if (folio) {
>>> + folio_unlock(folio);
>>> + folio_batch_add(&fbatch, folio);
>>> + fbatch.i++;
>>> + }
>>> }
>>> - if (folio) {
>>> - folio_unlock(folio);
>>> + if (folio) {
>>> page = folio_file_page(folio, index);
>>> if (PageHWPoison(page)) {
>>> - folio_put(folio);
>>> error = -EIO;
>>> break;
>>> }
>>
>> I haven't tested it yet, but I'm sure this will break the
>> fallback_page_copy mode.
>>
>> You're fetching from the batch at folio granularity here, but in
>> fallback_page_copy mode, we still copy the data at page granularity.
>
> Yes, that's a bug, Sashika has already reported it. I’ll fix it in the
> next version.
Good.
> Sashika also reported another potential issue below, but I think that is
> a misunderstanding, because a folio fetched from the swap cache is
> already marked Uptodate before being added to the page cache. What do
> you think?
I'm not concerned about swap-in folios, since we already ensure the
folio is uptodate when swapping out.
What I'm worried about is that this change moves the
folio_test_uptodate() check outside of the folio lock, which could
introduce some race? Of course, with the original logic, the folio state
could also transition from !uptodate to uptodate after the folio
is unlocked (I need more thought).
Another race condition that needs to be addressed is, when getting the
folio locklessly via filemap_get_folios_contig(), there could be a
concurrent race with swap-out (because you removed the folio->mapping
check under folio lock). This could result in reading zero data when it
shouldn't (the folio actually needs to be swapped in).
next prev parent reply other threads:[~2026-05-26 3:11 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-20 10:15 [PATCH v1 0/5] mm/shmem: optimize read with reduced xarray lookups and " Chi Zhiling
2026-05-20 10:15 ` [PATCH v1 1/5] mm/filemap: reduce unnecessary xarray lookups when read cached pages Chi Zhiling
2026-05-20 10:15 ` [PATCH v1 2/5] mm/filemap: reduce xarray lookups in filemap_get_folios_contig() Chi Zhiling
2026-05-20 10:15 ` [PATCH v1 3/5] mm/shmem: make SGP_NOALLOC succeed on hole like SGP_READ Chi Zhiling
2026-05-25 7:10 ` Baolin Wang
2026-05-25 8:14 ` Chi Zhiling
2026-05-25 8:44 ` Baolin Wang
2026-05-20 10:15 ` [PATCH v1 4/5] mm/shmem: introduce copy_zero_to_iter() for large zeroing Chi Zhiling
2026-05-20 10:15 ` [PATCH v1 5/5] mm/shmem: optimize file read with folio batching Chi Zhiling
2026-05-25 8:37 ` Baolin Wang
2026-05-25 9:47 ` Chi Zhiling
2026-05-26 3:11 ` Baolin Wang [this message]
2026-05-26 7:12 ` Chi Zhiling
2026-06-01 11:20 ` Baolin Wang
2026-06-01 14:37 ` Chi Zhiling
2026-05-22 0:14 ` [PATCH v1 0/5] mm/shmem: optimize read with reduced xarray lookups and " Andrew Morton
2026-05-22 1:36 ` Chi Zhiling
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=6881f92c-972a-4b7a-b3c0-93a91ff38b88@linux.alibaba.com \
--to=baolin.wang@linux.alibaba.com \
--cc=akpm@linux-foundation.org \
--cc=baohua@kernel.org \
--cc=chizhiling@163.com \
--cc=chizhiling@kylinos.cn \
--cc=david@kernel.org \
--cc=dev.jain@arm.com \
--cc=hughd@google.com \
--cc=jack@suse.cz \
--cc=lance.yang@linux.dev \
--cc=liam@infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=npache@redhat.com \
--cc=ryan.roberts@arm.com \
--cc=willy@infradead.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®