Linux filesystem development
 help / color / mirror / Atom feed
From: Joanne Koong <joannelkoong@gmail.com>
To: miklos@szeredi.hu, linux-fsdevel@vger.kernel.org
Cc: josef@toxicpanda.com, bernd.schubert@fastmail.fm,
	willy@infradead.org, jefflexu@linux.alibaba.com,
	shakeel.butt@linux.dev, jlayton@kernel.org, kernel-team@meta.com
Subject: [PATCH v3 10/12] fuse: optimize direct io large folios processing
Date: Fri, 13 Dec 2024 14:18:16 -0800	[thread overview]
Message-ID: <20241213221818.322371-11-joannelkoong@gmail.com> (raw)
In-Reply-To: <20241213221818.322371-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>
---
 fs/fuse/file.c | 52 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 39 insertions(+), 13 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 971624557810..bbc862c1b3fa 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1484,7 +1484,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,
@@ -1496,23 +1497,48 @@ 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++) {
+		/*
+		 * 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 = 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);
+			unsigned int offset;
+			unsigned int len;
+
+			WARN_ON(!folio);
+
+			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.43.5


  parent reply	other threads:[~2024-12-13 22:23 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-13 22:18 [PATCH v3 00/12] fuse: support large folios Joanne Koong
2024-12-13 22:18 ` [PATCH v3 01/12] fuse: support copying " Joanne Koong
2024-12-13 22:18 ` [PATCH v3 02/12] fuse: support large folios for retrieves Joanne Koong
2024-12-13 22:18 ` [PATCH v3 03/12] fuse: refactor fuse_fill_write_pages() Joanne Koong
2024-12-13 22:18 ` [PATCH v3 04/12] fuse: support large folios for writethrough writes Joanne Koong
2024-12-19 18:08   ` Jeff Layton
2024-12-19 20:24     ` Matthew Wilcox
2024-12-13 22:18 ` [PATCH v3 05/12] fuse: support large folios for folio reads Joanne Koong
2024-12-13 22:18 ` [PATCH v3 06/12] fuse: support large folios for symlinks Joanne Koong
2024-12-13 22:18 ` [PATCH v3 07/12] fuse: support large folios for stores Joanne Koong
2024-12-13 22:18 ` [PATCH v3 08/12] fuse: support large folios for queued writes Joanne Koong
2024-12-13 22:18 ` [PATCH v3 09/12] fuse: support large folios for readahead Joanne Koong
2024-12-13 22:18 ` Joanne Koong [this message]
2024-12-13 22:18 ` [PATCH v3 11/12] fuse: support large folios for writeback Joanne Koong
2024-12-13 22:18 ` [PATCH v3 12/12] fuse: enable large folios Joanne Koong
2024-12-19 18:12 ` [PATCH v3 00/12] fuse: support " Jeff Layton
2025-01-22 23:23 ` Joanne Koong
2025-01-23  1:24   ` Jingbo Xu
2025-01-23 18:05     ` Joanne Koong
2025-01-23 18:24   ` Matthew Wilcox
2025-01-23 18:42     ` Joanne Koong

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=20241213221818.322371-11-joannelkoong@gmail.com \
    --to=joannelkoong@gmail.com \
    --cc=bernd.schubert@fastmail.fm \
    --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=shakeel.butt@linux.dev \
    --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