From: Filipe Manana Date: Fri, 17 Oct 2025 14:47:59 +0000 (+0100) Subject: btrfs: avoid used space computation when trying to grant tickets X-Git-Tag: v6.19-rc1~167^2~98 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a5f8f64aa3377b470945252f926e2cbb5a931c11;p=thirdparty%2Fkernel%2Flinux.git 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 Signed-off-by: Filipe Manana Reviewed-by: David Sterba Signed-off-by: David Sterba --- diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c index 0fdf60f05228b..f5ff51680f412 100644 --- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -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;