Skip to content

Commit

Permalink
btrfs: zoned: use greedy gc for auto reclaim
Browse files Browse the repository at this point in the history
Currently auto reclaim of unusable zones reclaims the block-groups in
the order they have been added to the reclaim list.

Change this to a greedy algorithm by sorting the list so we have the
block-groups with the least amount of valid bytes reclaimed first.

Note: we can't splice the block groups from reclaim_bgs to let the sort
happen outside of the lock. The block groups can be still in use by
other parts eg. via bg_list and we must hold unused_bgs_lock while
processing them.

Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: David Sterba <dsterba@suse.com>
[ write note and comment why we can't splice the list ]
Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
Johannes Thumshirn authored and David Sterba committed Oct 26, 2021
1 parent 813ebc1 commit 2ca0ec7
Showing 1 changed file with 22 additions and 0 deletions.
22 changes: 22 additions & 0 deletions fs/btrfs/block-group.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0

#include <linux/list_sort.h>
#include "misc.h"
#include "ctree.h"
#include "block-group.h"
Expand Down Expand Up @@ -1486,6 +1487,21 @@ void btrfs_mark_bg_unused(struct btrfs_block_group *bg)
spin_unlock(&fs_info->unused_bgs_lock);
}

/*
* We want block groups with a low number of used bytes to be in the beginning
* of the list, so they will get reclaimed first.
*/
static int reclaim_bgs_cmp(void *unused, const struct list_head *a,
const struct list_head *b)
{
const struct btrfs_block_group *bg1, *bg2;

bg1 = list_entry(a, struct btrfs_block_group, bg_list);
bg2 = list_entry(b, struct btrfs_block_group, bg_list);

return bg1->used > bg2->used;
}

void btrfs_reclaim_bgs_work(struct work_struct *work)
{
struct btrfs_fs_info *fs_info =
Expand All @@ -1510,6 +1526,12 @@ void btrfs_reclaim_bgs_work(struct work_struct *work)
}

spin_lock(&fs_info->unused_bgs_lock);
/*
* Sort happens under lock because we can't simply splice it and sort.
* The block groups might still be in use and reachable via bg_list,
* and their presence in the reclaim_bgs list must be preserved.
*/
list_sort(NULL, &fs_info->reclaim_bgs, reclaim_bgs_cmp);
while (!list_empty(&fs_info->reclaim_bgs)) {
u64 zone_unusable;
int ret = 0;
Expand Down

0 comments on commit 2ca0ec7

Please sign in to comment.