Skip to content
  • Nate Dailey's avatar
    raid1: prevent freeze_array/wait_all_barriers deadlock · f6eca2d4
    Nate Dailey authored
    
    
    If freeze_array is attempted in the middle of close_sync/
    wait_all_barriers, deadlock can occur.
    
    freeze_array will wait for nr_pending and nr_queued to line up.
    wait_all_barriers increments nr_pending for each barrier bucket, one
    at a time, but doesn't actually issue IO that could be counted in
    nr_queued. So freeze_array is blocked until wait_all_barriers
    completes and allow_all_barriers runs. At the same time, when
    _wait_barrier sees array_frozen == 1, it stops and waits for
    freeze_array to complete.
    
    Prevent the deadlock by making close_sync call _wait_barrier and
    _allow_barrier for one bucket at a time, instead of deferring the
    _allow_barrier calls until after all _wait_barriers are complete.
    
    Signed-off-by: default avatarNate Dailey <nate.dailey@stratus.com>
    Fix: fd76863e
    
    (RAID1: a new I/O barrier implementation to remove resync window)
    Reviewed-by: default avatarColy Li <colyli@suse.de>
    Cc: stable@vger.kernel.org (v4.11)
    Signed-off-by: default avatarShaohua Li <shli@fb.com>
    f6eca2d4