btrfs: avoid extra tree search at btrfs_clear_extent_bit_changeset()
authorFilipe Manana <fdmanana@suse.com>
Wed, 9 Apr 2025 16:15:35 +0000 (17:15 +0100)
committerDavid Sterba <dsterba@suse.com>
Thu, 15 May 2025 12:30:51 +0000 (14:30 +0200)
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 <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/extent-io-tree.c

index f8b16c01c85620334e78642ae980727398de951d..7a5c59b89173d629975c00bc0071c48656db787d 100644 (file)
@@ -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 ---- |