btrfs: avoid used space computation when trying to grant tickets

In btrfs_try_granting_tickets(), we call btrfs_can_overcommit() and that
calls btrfs_space_info_used(). But we already keep track, in the 'used'
local variable, of the used space in the space_info, so we are just
repeating the same computation and doing an extra function call while we
are holding the space_info's spinlock, which is heavily used by the space
reservation and flushing code.

So add a local variant of btrfs_can_overcommit() that takes in the used
space as an argument and therefore does not call btrfs_space_info_used(),
and use it in btrfs_try_granting_tickets().

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
Filipe Manana
2025-10-17 15:47:59 +01:00
committed by David Sterba
parent 563ef2befb
commit a5f8f64aa3

View File

@@ -490,10 +490,29 @@ static u64 calc_available_free_space(const struct btrfs_space_info *space_info,
return avail;
}
static inline bool check_can_overcommit(const struct btrfs_space_info *space_info,
u64 space_info_used_bytes, u64 bytes,
enum btrfs_reserve_flush_enum flush)
{
const u64 avail = calc_available_free_space(space_info, flush);
return (space_info_used_bytes + bytes < space_info->total_bytes + avail);
}
static inline bool can_overcommit(const struct btrfs_space_info *space_info,
u64 space_info_used_bytes, u64 bytes,
enum btrfs_reserve_flush_enum flush)
{
/* Don't overcommit when in mixed mode. */
if (space_info->flags & BTRFS_BLOCK_GROUP_DATA)
return false;
return check_can_overcommit(space_info, space_info_used_bytes, bytes, flush);
}
bool btrfs_can_overcommit(const struct btrfs_space_info *space_info, u64 bytes,
enum btrfs_reserve_flush_enum flush)
{
u64 avail;
u64 used;
/* Don't overcommit when in mixed mode */
@@ -501,9 +520,8 @@ bool btrfs_can_overcommit(const struct btrfs_space_info *space_info, u64 bytes,
return false;
used = btrfs_space_info_used(space_info, true);
avail = calc_available_free_space(space_info, flush);
return (used + bytes < space_info->total_bytes + avail);
return check_can_overcommit(space_info, used, bytes, flush);
}
static void remove_ticket(struct btrfs_space_info *space_info,
@@ -539,7 +557,7 @@ again:
/* Check and see if our ticket can be satisfied now. */
if (used_after <= space_info->total_bytes ||
btrfs_can_overcommit(space_info, ticket->bytes, flush)) {
can_overcommit(space_info, used, ticket->bytes, flush)) {
btrfs_space_info_update_bytes_may_use(space_info, ticket->bytes);
remove_ticket(space_info, ticket);
ticket->bytes = 0;