btrfs: wakeup cleaner thread when adding delayed iput
authorJosef Bacik <josef@toxicpanda.com>
Fri, 11 Jan 2019 15:21:02 +0000 (10:21 -0500)
committerDavid Sterba <dsterba@suse.com>
Fri, 18 Jan 2019 16:27:23 +0000 (17:27 +0100)
The cleaner thread usually takes care of delayed iputs, with the
exception of the btrfs_end_transaction_throttle path.  Delaying iputs
means we are potentially delaying the eviction of an inode and it's
respective space.  The cleaner thread only gets woken up every 30
seconds, or when we require space.  If there are a lot of inodes that
need to be deleted we could induce a serious amount of latency while we
wait for these inodes to be evicted.  So instead wakeup the cleaner if
it's not already awake to process any new delayed iputs we add to the
list.  If we suddenly need space we will less likely be backed up
behind a bunch of inodes that are waiting to be deleted, and we could
possibly free space before we need to get into the flushing logic which
will save us some latency.

Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/inode.c

index 34019c8b6158b4c46fcb5eafda0dd8a02d35bf36..8b1d06fa222dddb92bab398573856750cf5ea271 100644 (file)
@@ -787,6 +787,9 @@ enum {
         * main phase. The fs_info::balance_ctl is initialized.
         */
        BTRFS_FS_BALANCE_RUNNING,
+
+       /* Indicate that the cleaner thread is awake and doing something. */
+       BTRFS_FS_CLEANER_RUNNING,
 };
 
 struct btrfs_fs_info {
index 18eefc5b25327c14c937455ca41c3a07686eb5d2..6a2a2a9517058b429b286557fd0a2b1a512c833d 100644 (file)
@@ -1682,6 +1682,8 @@ static int cleaner_kthread(void *arg)
        while (1) {
                again = 0;
 
+               set_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags);
+
                /* Make the cleaner go to sleep early. */
                if (btrfs_need_cleaner_sleep(fs_info))
                        goto sleep;
@@ -1728,6 +1730,7 @@ static int cleaner_kthread(void *arg)
                 */
                btrfs_delete_unused_bgs(fs_info);
 sleep:
+               clear_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags);
                if (kthread_should_park())
                        kthread_parkme();
                if (kthread_should_stop())
index b6025b5d0b25634dd545c31b002adc241fa0b8de..5c349667c761b5fed05a15d565c69eff015709e8 100644 (file)
@@ -3251,6 +3251,8 @@ void btrfs_add_delayed_iput(struct inode *inode)
        ASSERT(list_empty(&binode->delayed_iput));
        list_add_tail(&binode->delayed_iput, &fs_info->delayed_iputs);
        spin_unlock(&fs_info->delayed_iput_lock);
+       if (!test_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags))
+               wake_up_process(fs_info->cleaner_kthread);
 }
 
 void btrfs_run_delayed_iputs(struct btrfs_fs_info *fs_info)