From: Joanne Koong <joannelkoong@gmail.com>
To: miklos@szeredi.hu
Cc: linux-fsdevel@vger.kernel.org, bernd.schubert@fastmail.fm,
jlayton@kernel.org, jefflexu@linux.alibaba.com,
josef@toxicpanda.com, willy@infradead.org, kernel-team@meta.com,
Bernd Schubert <bschubert@ddn.com>
Subject: [PATCH v6 10/11] fuse: optimize direct io large folios processing
Date: Mon, 12 May 2025 15:58:39 -0700 [thread overview]
Message-ID: <20250512225840.826249-11-joannelkoong@gmail.com> (raw)
In-Reply-To: <20250512225840.826249-1-joannelkoong@gmail.com>
Optimize processing folios larger than one page size for the direct io
case. If contiguous pages are part of the same folio, collate the
processing instead of processing each page in the folio separately.
Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Bernd Schubert <bschubert@ddn.com>
---
fs/fuse/file.c | 55 +++++++++++++++++++++++++++++++++++++-------------
1 file changed, 41 insertions(+), 14 deletions(-)
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 07ff81469a59..e4d86ced9aac 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1491,7 +1491,8 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
}
while (nbytes < *nbytesp && nr_pages < max_pages) {
- unsigned nfolios, i;
+ struct folio *prev_folio = NULL;
+ unsigned npages, i;
size_t start;
ret = iov_iter_extract_pages(ii, &pages,
@@ -1503,23 +1504,49 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
nbytes += ret;
- nfolios = DIV_ROUND_UP(ret + start, PAGE_SIZE);
+ npages = DIV_ROUND_UP(ret + start, PAGE_SIZE);
- for (i = 0; i < nfolios; i++) {
- struct folio *folio = page_folio(pages[i]);
- unsigned int offset = start +
- (folio_page_idx(folio, pages[i]) << PAGE_SHIFT);
- unsigned int len = min_t(unsigned int, ret, PAGE_SIZE - start);
+ /*
+ * We must check each extracted page. We can't assume every page
+ * in a large folio is used. For example, userspace may mmap() a
+ * file PROT_WRITE, MAP_PRIVATE, and then store to the middle of
+ * a large folio, in which case the extracted pages could be
+ *
+ * folio A page 0
+ * folio A page 1
+ * folio B page 0
+ * folio A page 3
+ *
+ * where folio A belongs to the file and folio B is an anonymous
+ * COW page.
+ */
+ for (i = 0; i < npages && ret; i++) {
+ struct folio *folio;
+ unsigned int offset;
+ unsigned int len;
+
+ WARN_ON(!pages[i]);
+ folio = page_folio(pages[i]);
+
+ len = min_t(unsigned int, ret, PAGE_SIZE - start);
+
+ if (folio == prev_folio && pages[i] != pages[i - 1]) {
+ WARN_ON(ap->folios[ap->num_folios - 1] != folio);
+ ap->descs[ap->num_folios - 1].length += len;
+ WARN_ON(ap->descs[ap->num_folios - 1].length > folio_size(folio));
+ } else {
+ offset = start + (folio_page_idx(folio, pages[i]) << PAGE_SHIFT);
+ ap->descs[ap->num_folios].offset = offset;
+ ap->descs[ap->num_folios].length = len;
+ ap->folios[ap->num_folios] = folio;
+ start = 0;
+ ap->num_folios++;
+ prev_folio = folio;
+ }
- ap->descs[ap->num_folios].offset = offset;
- ap->descs[ap->num_folios].length = len;
- ap->folios[ap->num_folios] = folio;
- start = 0;
ret -= len;
- ap->num_folios++;
}
-
- nr_pages += nfolios;
+ nr_pages += npages;
}
kfree(pages);
--
2.47.1
next prev parent reply other threads:[~2025-05-12 22:59 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-12 22:58 [PATCH v6 00/11] fuse: support large folios Joanne Koong
2025-05-12 22:58 ` [PATCH v6 01/11] fuse: support copying " Joanne Koong
2025-05-14 0:18 ` Matthew Wilcox
2025-05-14 22:59 ` Joanne Koong
2025-05-15 2:05 ` Matthew Wilcox
2025-05-15 18:50 ` Joanne Koong
2025-05-15 8:26 ` Miklos Szeredi
2025-05-15 17:53 ` Joanne Koong
2025-05-16 9:47 ` Miklos Szeredi
2025-05-12 22:58 ` [PATCH v6 02/11] fuse: support large folios for retrieves Joanne Koong
2025-05-12 22:58 ` [PATCH v6 03/11] fuse: refactor fuse_fill_write_pages() Joanne Koong
2025-05-12 22:58 ` [PATCH v6 04/11] fuse: support large folios for writethrough writes Joanne Koong
2025-05-12 22:58 ` [PATCH v6 05/11] fuse: support large folios for folio reads Joanne Koong
2025-05-12 22:58 ` [PATCH v6 06/11] fuse: support large folios for symlinks Joanne Koong
2025-05-12 22:58 ` [PATCH v6 07/11] fuse: support large folios for stores Joanne Koong
2025-05-12 22:58 ` [PATCH v6 08/11] fuse: support large folios for queued writes Joanne Koong
2025-05-12 22:58 ` [PATCH v6 09/11] fuse: support large folios for readahead Joanne Koong
2025-05-12 22:58 ` Joanne Koong [this message]
2025-05-13 7:19 ` [PATCH v6 10/11] fuse: optimize direct io large folios processing Miklos Szeredi
2025-05-13 20:39 ` Joanne Koong
2025-05-15 8:27 ` Miklos Szeredi
2025-05-12 22:58 ` [PATCH v6 11/11] fuse: support large folios for writeback Joanne Koong
2025-05-13 7:32 ` [PATCH v6 00/11] fuse: support large folios Miklos Szeredi
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=20250512225840.826249-11-joannelkoong@gmail.com \
--to=joannelkoong@gmail.com \
--cc=bernd.schubert@fastmail.fm \
--cc=bschubert@ddn.com \
--cc=jefflexu@linux.alibaba.com \
--cc=jlayton@kernel.org \
--cc=josef@toxicpanda.com \
--cc=kernel-team@meta.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=willy@infradead.org \
/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;
as well as URLs for NNTP newsgroup(s).