Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
btrfs: switch btrfs_buffered_write() to page-by-page pace
Before this patch, btrfs_buffered_write() do page copy in a 8 pages batch. While for EXT4, it uses generic_perform_write() which does page by page copy. This 8 pages batch behavior makes a lot of things more complex: - More complex error handling Now we need to handle all errors for half written case. - More complex advance check Since for 8 pages, we need to consider cases like 4 pages copied. This makes we need to release reserved space for the untouched 4 pages. - More wrappers for multi-pages operations The most obvious one is btrfs_copy_from_user(), which introduces way more complexity than we need. This patch will change the behavior by going to the page-by-page pace, each time we only reserve space for one page, do one page copy. There are still a lot of complexity remained, mostly for short copy, non-uptodate page and extent locking. But that's more or less the same as the generic_perform_write(). The performance is the same for 4K block size buffered write, but has an obvious impact when using multiple pages siuzed block size: The test involves writing a 128MiB file, which is smaller than 1/8th of the system memory. Speed (MiB/sec) Ops (ops/sec) Unpatched: 931.498 14903.9756 Patched: 447.606 7161.6806 In fact, if we account the execution time of btrfs_buffered_write(), meta/data rsv and later page dirty takes way more time than memory copy: Patched: nr_runs = 32768 total_prepare_ns = 66908022 total_copy_ns = 75532103 total_cleanup_ns = 135749090 Unpatched: nr_runs = 2176 total_prepare_ns = 7425773 total_copy_ns = 87780898 total_cleanup_ns = 37704811 The patched behavior is now similar to EXT4, the buffered write remain mostly unchanged for from 4K blocksize and larger. On the other hand, XFS uses iomap, which supports multi-page reserve and copy, leading to similar performance of unpatched btrfs. It looks like that we'd better go iomap routine other than the generic_perform_write(). Signed-off-by: Qu Wenruo <wqu@suse.com>
- Loading branch information