]> git.hungrycats.org Git - linux/commitdiff
btrfs: do not block on deleted bgs mutex in the cleaner
authorJosef Bacik <josef@toxicpanda.com>
Fri, 18 Dec 2020 19:24:19 +0000 (14:24 -0500)
committerZygo Blaxell <ce3g8jdj@umail.furryterror.org>
Sun, 5 Dec 2021 08:11:24 +0000 (03:11 -0500)
While running some stress tests I started getting hung task messages.
This is because the delete unused block groups code has to take the
delete_unused_bgs_mutex to do it's work, which is taken by balance to
make sure we don't delete block groups while we're balancing.

The problem is that balance can take a while, and so we were getting
hung task warnings.  We don't need to block and run these things, and
the cleaner is needed to do other work, so trylock on this mutex and
just bail if we can't acquire it right away.

Reviewed-by: Nikolay Borisov <nborisov@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
(cherry picked from commit ddfd08cb0484e491cae47a76ead051a168a0e644)
(cherry picked from commit 856a617ed3f203462e72a0dfbf2be263a50f4a1c)

fs/btrfs/block-group.c

index 3cf1b953f52362badd73ca405d909bb993f924e1..1838e997e530904a22d56e865d7e65403d154e37 100644 (file)
@@ -1267,6 +1267,13 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
        if (!test_bit(BTRFS_FS_OPEN, &fs_info->flags))
                return;
 
+       /*
+        * Long running balances can keep us blocked here for eternity, so
+        * simply skip deletion if we're unable to get the mutex.
+        */
+       if (!mutex_trylock(&fs_info->delete_unused_bgs_mutex))
+               return;
+
        spin_lock(&fs_info->unused_bgs_lock);
        while (!list_empty(&fs_info->unused_bgs)) {
                int trimming;
@@ -1286,8 +1293,6 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
 
                btrfs_discard_cancel_work(&fs_info->discard_ctl, block_group);
 
-               mutex_lock(&fs_info->delete_unused_bgs_mutex);
-
                /* Don't want to race with allocators so take the groups_sem */
                down_write(&space_info->groups_sem);
 
@@ -1431,11 +1436,11 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
 end_trans:
                btrfs_end_transaction(trans);
 next:
-               mutex_unlock(&fs_info->delete_unused_bgs_mutex);
                btrfs_put_block_group(block_group);
                spin_lock(&fs_info->unused_bgs_lock);
        }
        spin_unlock(&fs_info->unused_bgs_lock);
+       mutex_unlock(&fs_info->delete_unused_bgs_mutex);
        return;
 
 flip_async: