From: Filipe Manana Date: Wed, 9 Apr 2025 16:15:35 +0000 (+0100) Subject: btrfs: avoid extra tree search at btrfs_clear_extent_bit_changeset() X-Git-Tag: v6.16-rc1~214^2~72 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6c28102f9ac4eea321e5421c248ca17983a9760d;p=thirdparty%2Flinux.git btrfs: avoid extra tree search at btrfs_clear_extent_bit_changeset() When we find an extent state that starts before our range's start we split it and jump into the 'search_again' label with our start offset remaining the same, making us then go to the 'again' label and search again for an extent state that contains the 'start' offset, and this time it finds the same extent state but with its start offset set to our range's start offset (due to the split). This is because we have consumed the preallocated extent state record and we may need to split again, and by jumping to 'again' we release the spinlock, allocate a new prealloc state and restart the search. However we may not need to restart and allocate a new extent state in case we don't find extent states that cross our end offset, therefore no need for further extent state splits, or we may be able to do an atomic allocation (which is quick even if it fails). In these cases it's a waste to restart the search. So change the behaviour to do the restart only if we need to reschedule, otherwise fall through - if we need to allocate an extent state for split operations, we will try an atomic allocation and if that fails we will do the restart as before. Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba --- diff --git a/fs/btrfs/extent-io-tree.c b/fs/btrfs/extent-io-tree.c index f8b16c01c8562..7a5c59b89173d 100644 --- a/fs/btrfs/extent-io-tree.c +++ b/fs/btrfs/extent-io-tree.c @@ -699,7 +699,13 @@ hit_next: state = clear_state_bit(tree, state, bits, wake, changeset); goto next; } - goto search_again; + if (need_resched()) + goto search_again; + /* + * Fallthrough and try atomic extent state allocation if needed. + * If it fails we'll jump to 'search_again' retry the allocation + * in non-atomic mode and start the search again. + */ } /* * | ---- desired range ---- |