mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	btrfs: increase direct io read size limit to 256 sectors
Btrfs currently limits direct I/O reads to a single sector, which goes
back to commit c329861da4 ("Btrfs: don't allocate a separate csums
array for direct reads") from Josef.  That commit changes the direct I/O
code to ".. use the private part of the io_tree for our csums.", but ten
years later that isn't how checksums for direct reads work, instead they
use a csums allocation on a per-btrfs_dio_private basis (which have their
own performance problem for small I/O, but that will be addressed later).
There is no fundamental limit in btrfs itself to limit the I/O size
except for the size of the checksum array that scales linearly with
the number of sectors in an I/O.  Pick a somewhat arbitrary limit of
256 limits, which matches what the buffered reads typically see as
the upper limit as the limit for direct I/O as well.
This significantly improves direct read performance.  For example a fio
run doing 1 MiB aio reads with a queue depth of 1 roughly triples the
throughput:
Baseline:
READ: bw=65.3MiB/s (68.5MB/s), 65.3MiB/s-65.3MiB/s (68.5MB/s-68.5MB/s), io=19.1GiB (20.6GB), run=300013-300013msec
With this patch:
READ: bw=196MiB/s (206MB/s), 196MiB/s-196MiB/s (206MB/s-206MB/s), io=57.5GiB (61.7GB), run=300006-300006msc
Reviewed-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: David Sterba <dsterba@suse.com>
			
			
This commit is contained in:
		
							parent
							
								
									f6065f8ede
								
							
						
					
					
						commit
						ee5b46a353
					
				
					 2 changed files with 12 additions and 1 deletions
				
			
		| 
						 | 
					@ -7578,8 +7578,12 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
 | 
				
			||||||
	const u64 data_alloc_len = length;
 | 
						const u64 data_alloc_len = length;
 | 
				
			||||||
	bool unlock_extents = false;
 | 
						bool unlock_extents = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Cap the size of reads to that usually seen in buffered I/O as we need
 | 
				
			||||||
 | 
						 * to allocate a contiguous array for the checksums.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
	if (!write)
 | 
						if (!write)
 | 
				
			||||||
		len = min_t(u64, len, fs_info->sectorsize);
 | 
							len = min_t(u64, len, fs_info->sectorsize * BTRFS_MAX_BIO_SECTORS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockstart = start;
 | 
						lockstart = start;
 | 
				
			||||||
	lockend = start + len - 1;
 | 
						lockend = start + len - 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -354,6 +354,13 @@ struct btrfs_fs_devices {
 | 
				
			||||||
				- 2 * sizeof(struct btrfs_chunk))	\
 | 
									- 2 * sizeof(struct btrfs_chunk))	\
 | 
				
			||||||
				/ sizeof(struct btrfs_stripe) + 1)
 | 
									/ sizeof(struct btrfs_stripe) + 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Maximum number of sectors for a single bio to limit the size of the
 | 
				
			||||||
 | 
					 * checksum array.  This matches the number of bio_vecs per bio and thus the
 | 
				
			||||||
 | 
					 * I/O size for buffered I/O.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define BTRFS_MAX_BIO_SECTORS				(256)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Additional info to pass along bio.
 | 
					 * Additional info to pass along bio.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue