• Mike Snitzer's avatar
    dm mpath: restrict queue_if_no_path state machine · 553ec94c
    Mike Snitzer authored
    Do not allow saving disabled queue_if_no_path if already saved as
    enabled; implies multiple suspends (which shouldn't ever happen).  Log
    if this unlikely scenario is ever triggered.
    
    Also, only write MPATHF_SAVED_QUEUE_IF_NO_PATH during presuspend or if
    "fail_if_no_path" message.  MPATHF_SAVED_QUEUE_IF_NO_PATH is no longer
    always modified, e.g.: even if queue_if_no_path()'s save_old_value
    argument wasn't set.  This just implies a bit tighter control over
    the management of MPATHF_SAVED_QUEUE_IF_NO_PATH.  Side-effect is
    multipath_resume() doesn't reset MPATHF_QUEUE_IF_NO_PATH unless
    MPATHF_SAVED_QUEUE_IF_NO_PATH was set (during presuspend); and at that
    time the MPATHF_SAVED_QUEUE_IF_NO_PATH bit gets cleared.  So
    MPATHF_SAVED_QUEUE_IF_NO_PATH's use is much more narrow in scope.
    
    Last, but not least, do _not_ disable queue_if_no_path during noflush
    suspend.  There is no need/benefit to saving off queue_if_no_path via
    MPATHF_SAVED_QUEUE_IF_NO_PATH and clearing MPATHF_QUEUE_IF_NO_PATH for
    noflush suspend -- by avoiding this needless queue_if_no_path flag
    churn there is less potential for MPATHF_QUEUE_IF_NO_PATH to get lost.
    Which avoids potential for IOs to be errored back up to userspace
    during DM multipath's handling of path failures.
    
    That said, this last change papers over a reported issue concerning
    request-based dm-multipath's interaction with blk-mq, relative to
    suspend and resume: multipath_endio is being called _before_
    multipath_resume.  This should never happen if DM suspend's
    blk_mq_quiesce_queue() + dm_wait_for_completion() is genuinely waiting
    for all inflight blk-mq requests to complete.  Similarly:
    drivers/md/dm.c:__dm_resume() clearly calls dm_table_resume_targets()
    _before_ dm_start_queue()'s blk_mq_unquiesce_queue() is called.  If
    the queue isn't even restarted until after multipath_resume(); the BIG
    question that still needs answering is: how can multipath_end_io beat
    multipath_resume in a race!?
    Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
    553ec94c
dm-mpath.c 52.2 KB