mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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).

  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®