btrfs: wakeup cleaner thread when adding delayed iput
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>
This commit is contained in:
parent
3ec9a4c81c
commit
fd340d0f68
|
@ -787,6 +787,9 @@ enum {
|
||||||
* main phase. The fs_info::balance_ctl is initialized.
|
* main phase. The fs_info::balance_ctl is initialized.
|
||||||
*/
|
*/
|
||||||
BTRFS_FS_BALANCE_RUNNING,
|
BTRFS_FS_BALANCE_RUNNING,
|
||||||
|
|
||||||
|
/* Indicate that the cleaner thread is awake and doing something. */
|
||||||
|
BTRFS_FS_CLEANER_RUNNING,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct btrfs_fs_info {
|
struct btrfs_fs_info {
|
||||||
|
|
|
@ -1682,6 +1682,8 @@ static int cleaner_kthread(void *arg)
|
||||||
while (1) {
|
while (1) {
|
||||||
again = 0;
|
again = 0;
|
||||||
|
|
||||||
|
set_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags);
|
||||||
|
|
||||||
/* Make the cleaner go to sleep early. */
|
/* Make the cleaner go to sleep early. */
|
||||||
if (btrfs_need_cleaner_sleep(fs_info))
|
if (btrfs_need_cleaner_sleep(fs_info))
|
||||||
goto sleep;
|
goto sleep;
|
||||||
|
@ -1728,6 +1730,7 @@ static int cleaner_kthread(void *arg)
|
||||||
*/
|
*/
|
||||||
btrfs_delete_unused_bgs(fs_info);
|
btrfs_delete_unused_bgs(fs_info);
|
||||||
sleep:
|
sleep:
|
||||||
|
clear_bit(BTRFS_FS_CLEANER_RUNNING, &fs_info->flags);
|
||||||
if (kthread_should_park())
|
if (kthread_should_park())
|
||||||
kthread_parkme();
|
kthread_parkme();
|
||||||
if (kthread_should_stop())
|
if (kthread_should_stop())
|
||||||
|
|
|
@ -3251,6 +3251,8 @@ void btrfs_add_delayed_iput(struct inode *inode)
|
||||||
ASSERT(list_empty(&binode->delayed_iput));
|
ASSERT(list_empty(&binode->delayed_iput));
|
||||||
list_add_tail(&binode->delayed_iput, &fs_info->delayed_iputs);
|
list_add_tail(&binode->delayed_iput, &fs_info->delayed_iputs);
|
||||||
spin_unlock(&fs_info->delayed_iput_lock);
|
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)
|
void btrfs_run_delayed_iputs(struct btrfs_fs_info *fs_info)
|
||||||
|
|
Loading…
Reference in New Issue