• Yu Kuai's avatar
    md: fix stopping sync thread · f52f5c71
    Yu Kuai authored
    Currently sync thread is stopped from multiple contex:
     - idle_sync_thread
     - frozen_sync_thread
     - __md_stop_writes
     - md_set_readonly
     - do_md_stop
    
    And there are some problems:
    1) sync_work is flushed while reconfig_mutex is grabbed, this can
       deadlock because the work function will grab reconfig_mutex as well.
    2) md_reap_sync_thread() can't be called directly while md_do_sync() is
       not finished yet, for example, commit 130443d6 ("md: refactor
       idle/frozen_sync_thread() to fix deadlock").
    3) If MD_RECOVERY_RUNNING is not set, there is no need to stop
       sync_thread at all because sync_thread must not be registered.
    
    Factor out a helper stop_sync_thread(), so that above contex will behave
    the same. Fix 1) by flushing sync_work after reconfig_mutex is released,
    before waiting for sync_thread to be done; Fix 2) bt letting daemon thread
    to unregister sync_thread; Fix 3) by always checking MD_RECOVERY_RUNNING
    first.
    
    Fixes: db5e653d
    
     ("md: delay choosing sync action to md_start_sync()")
    Signed-off-by: default avatarYu Kuai <yukuai3@huawei.com>
    Signed-off-by: default avatarSong Liu <song@kernel.org>
    Link: https://lore.kernel.org/r/20231205094215.1824240-4-yukuai1@huaweicloud.com
    f52f5c71
md.c 263 KB