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