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

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

 




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





[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