Btrfs: wake up @scrub_pause_wait as much as we can
check if @scrubs_running=@scrubs_paused condition inside wait_event() is not an atomic operation which means we may inc/dec @scrub_running/ paused at any time. Let's wake up @scrub_pause_wait as much as we can to let commit transaction blocked less. An example below: Thread1 Thread2 |->scrub_blocked_if_needed() |->scrub_pending_trans_workers_inc |->increase @scrub_paused |->increase @scrub_running |->wake up scrub_pause_wait list |->scrub blocked |->increase @scrub_paused Thread3 is commiting transaction which is blocked at btrfs_scrub_pause(). So after Thread2 increase @scrub_paused, we meet the condition @scrub_paused=@scrub_running, but transaction will be still blocked until another calling to wake up @scrub_pause_wait. Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com> Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fb.com>
This commit is contained in:
Родитель
c0af8f0b1c
Коммит
32a447896c
|
@ -315,6 +315,16 @@ static void scrub_pending_trans_workers_inc(struct scrub_ctx *sctx)
|
||||||
atomic_inc(&fs_info->scrubs_running);
|
atomic_inc(&fs_info->scrubs_running);
|
||||||
atomic_inc(&fs_info->scrubs_paused);
|
atomic_inc(&fs_info->scrubs_paused);
|
||||||
mutex_unlock(&fs_info->scrub_lock);
|
mutex_unlock(&fs_info->scrub_lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check if @scrubs_running=@scrubs_paused condition
|
||||||
|
* inside wait_event() is not an atomic operation.
|
||||||
|
* which means we may inc/dec @scrub_running/paused
|
||||||
|
* at any time. Let's wake up @scrub_pause_wait as
|
||||||
|
* much as we can to let commit transaction blocked less.
|
||||||
|
*/
|
||||||
|
wake_up(&fs_info->scrub_pause_wait);
|
||||||
|
|
||||||
atomic_inc(&sctx->workers_pending);
|
atomic_inc(&sctx->workers_pending);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче