diff options
| author | Filipe Manana <fdmanana@suse.com> | 2025-10-17 14:57:27 +0100 |
|---|---|---|
| committer | David Sterba <dsterba@suse.com> | 2025-11-24 22:05:06 +0100 |
| commit | 60532c2136ea205c5db0a622e1a51420c8530d0f (patch) | |
| tree | 3967acb2a5481cfe16ee00a012253b9a9763703f /fs/btrfs/space-info.c | |
| parent | 063171a4f0fa25fe47331b4fee3f705484f1c690 (diff) | |
btrfs: avoid recomputing used space in btrfs_try_granting_tickets()
In every iteration of the loop we call btrfs_space_info_used() which sums
a bunch of fields from a space_info object. This implies doing a function
call besides the sum, and we are holding the space_info's spinlock while
we do this, so we want to keep the critical section as short as possible
since that spinlock is used in all the code for space reservation and
flushing (therefore it's heavily used).
So call btrfs_try_granting_tickets() only once, before entering the loop,
and then update it as we remove 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>
Diffstat (limited to 'fs/btrfs/space-info.c')
| -rw-r--r-- | fs/btrfs/space-info.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c index 8b1cf7f6c223..c0bad6914bb7 100644 --- a/fs/btrfs/space-info.c +++ b/fs/btrfs/space-info.c @@ -526,6 +526,7 @@ void btrfs_try_granting_tickets(struct btrfs_space_info *space_info) { struct list_head *head; enum btrfs_reserve_flush_enum flush = BTRFS_RESERVE_NO_FLUSH; + u64 used = btrfs_space_info_used(space_info, true); lockdep_assert_held(&space_info->lock); @@ -533,18 +534,20 @@ void btrfs_try_granting_tickets(struct btrfs_space_info *space_info) again: while (!list_empty(head)) { struct reserve_ticket *ticket; - u64 used = btrfs_space_info_used(space_info, true); + u64 used_after; ticket = list_first_entry(head, struct reserve_ticket, list); + used_after = used + ticket->bytes; /* Check and see if our ticket can be satisfied now. */ - if ((used + ticket->bytes <= space_info->total_bytes) || + if (used_after <= space_info->total_bytes || btrfs_can_overcommit(space_info, ticket->bytes, flush)) { btrfs_space_info_update_bytes_may_use(space_info, ticket->bytes); remove_ticket(space_info, ticket); ticket->bytes = 0; space_info->tickets_id++; wake_up(&ticket->wait); + used = used_after; } else { break; } |
