On 8/12/25 4:40 AM, Joanne Koong wrote: > 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); > + } JFYI fc->max_read shall also be honored when calculating max_order, otherwise the following warning in fuse_readahead() may be triggered. /* * Large folios belonging to fuse will never * have more pages than max_pages. */ WARN_ON(!pages); -- Thanks, Jingbo