[PATCH] fuse: enable large folios (if writeback cache is unused)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Large folios are only enabled if the writeback cache isn't on.
(Strictlimiting needs to be turned off if the writeback cache is used in
conjunction with large folios, else this tanks performance.)

Benchmarks showed noticeable improvements for writes (both sequential
and random). There were no performance differences seen for random reads
or direct IO. For sequential reads, there was no performance difference
seen for the first read (which populates the page cache) but subsequent
sequential reads showed a huge speedup.

Benchmarks were run using fio on the passthrough_hp fuse server:
~/libfuse/build/example/passthrough_hp ~/libfuse ~/fuse_mnt --nopassthrough --nocache

run fio in ~/fuse_mnt:
fio --name=test --ioengine=sync --rw=write --bs=1M --size=5G --numjobs=2 --ramp_time=30 --group_reporting=1

Results (tested on bs=256K, 1M, 5M) showed roughly a 15-20% increase in
write throughput and for sequential reads after the page cache has
already been populated, there was a ~800% speedup seen.

Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx>
---
 fs/fuse/file.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index adc4aa6810f5..2e7aae294c9e 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1167,9 +1167,10 @@ static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia,
 		pgoff_t index = pos >> PAGE_SHIFT;
 		unsigned int bytes;
 		unsigned int folio_offset;
+		fgf_t fgp = FGP_WRITEBEGIN | fgf_set_order(num);
 
  again:
-		folio = __filemap_get_folio(mapping, index, FGP_WRITEBEGIN,
+		folio = __filemap_get_folio(mapping, index, fgp,
 					    mapping_gfp_mask(mapping));
 		if (IS_ERR(folio)) {
 			err = PTR_ERR(folio);
@@ -3155,11 +3156,24 @@ void fuse_init_file_inode(struct inode *inode, unsigned int flags)
 {
 	struct fuse_inode *fi = get_fuse_inode(inode);
 	struct fuse_conn *fc = get_fuse_conn(inode);
+	unsigned int max_pages, max_order;
 
 	inode->i_fop = &fuse_file_operations;
 	inode->i_data.a_ops = &fuse_file_aops;
-	if (fc->writeback_cache)
+	if (fc->writeback_cache) {
 		mapping_set_writeback_may_deadlock_on_reclaim(&inode->i_data);
+	} else {
+		/*
+		 * Large folios are only enabled if the writeback cache isn't on.
+		 * If the writeback cache is on, large folios should only be
+		 * enabled in conjunction with strictlimiting turned off, else
+		 * performance tanks.
+		 */
+		max_pages = min(min(fc->max_write, fc->max_read) >> PAGE_SHIFT,
+				fc->max_pages);
+		max_order = ilog2(max_pages);
+		mapping_set_folio_order_range(inode->i_mapping, 0, max_order);
+	}
 
 	INIT_LIST_HEAD(&fi->write_files);
 	INIT_LIST_HEAD(&fi->queued_writes);
-- 
2.47.3





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux