summaryrefslogtreecommitdiff
path: root/tools/perf/scripts/python
diff options
context:
space:
mode:
authorBoris Burkov <boris@bur.io>2026-09-15 10:58:31 -0700
committerDavid Sterba <dsterba@suse.com>2026-10-12 19:16:21 +0200
commit220c44b1b90fbff746472cbb3dde778b02afbef9 (patch)
tree326e2edd82a3a4c3bfa16047e1dd1f34efe6890b /tools/perf/scripts/python
parent3bb5ed05c1ead17a12456d77591c773e1032c16a (diff)
downloadlinux-220c44b1b90fbff746472cbb3dde778b02afbef9.tar.gz
linux-220c44b1b90fbff746472cbb3dde778b02afbef9.zip
btrfs: pre-flush reflink source before taking inode locks
Consider the following sketch of a shell script: dd if=/dev/urandom of=/mnt/src bs=1M count=4096 cp --reflink=always /mnt/src /mnt/dst & sleep 0.1 # let the clone reach its flush time dd if=/mnt/src of=/dev/null bs=4K count=1 iflag=direct The current logic in reflink ensures the existence and stability of both the src and destination inode by locking them both and then flushing all dirty pages / ordered_extents under the inode lock. This blocks concurrent usage by even readers of the inode locks, like direct reads or seeks for the duration of writeback on the entirety of the two files. We observe this particular contention frequently in the Meta fleet. It is also a relatively common pattern to write the src file, then reflink it while it is still dirty, so that typical path naturally hits this contention. This workload motivates a relatively simple optimization: trigger the unavoidable src flushing outside the locked region. Therefore, do an optimistic btrfs_wait_ordered_range() without the locks while relying on the calls to btrfs_wait_ordered_range() under the locks in btrfs_remap_file_range_prep() to ensure correctness. In the worst case with concurrent writes while unlocked, we can end up doing the writeback twice, which I think is a reasonable price to pay to avoid victimizing innocent readers in a common case. With and without this patch, the above reproducer runs the reflink in the same ~0.5s on my system. Without the patch, the direct read blocks for basically the full duration of the reflink while with the patch it returns in a few milliseconds. Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Boris Burkov <boris@bur.io> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'tools/perf/scripts/python')
0 files changed, 0 insertions, 0 deletions