• Nicholas Bellinger's avatar
    scsi: target: Fix target_wait_for_sess_cmds breakage with active signals · 38fe73cc
    Nicholas Bellinger authored
    With the addition of commit 00d909a1 ("scsi: target: Make the session
    shutdown code also wait for commands that are being aborted") in v4.19-rc, it
    incorrectly assumes no signals will be pending for task_struct executing the
    normal session shutdown and I/O quiesce code-path.
    
    For example, iscsi-target and iser-target issue SIGINT to all kthreads as part
    of session shutdown.  This has been the behaviour since day one.
    
    As-is when signals are pending with se_cmds active in se_sess->sess_cmd_list,
    wait_event_interruptible_lock_irq_timeout() returns a negative number and
    immediately kills the machine because of the do while (ret <= 0) loop that was
    added in commit 00d909a1 to spin while backend I/O is taking any amount of
    extended time (say 30 seconds) to complete.
    
    Here's what it looks like in action with debug plus delayed backend I/O
    completion:
    
    [ 4951.909951] se_sess: 000000003e7e08fa before target_wait_for_sess_cmds
    [ 4951.914600] target_wait_for_sess_cmds: signal_pending: 1
    [ 4951.918015] wait_event_interruptible_lock_irq_timeout ret: -512 signal_pending: 1 loop count: 0
    [ 4951.921639] wait_event_interruptible_lock_irq_timeout ret: -512 signal_pending: 1 loop count: 1
    [ 4951.921944] wait_event_interruptible_lock_irq_timeout ret: -512 signal_pending: 1 loop count: 2
    [ 4951.921944] wait_event_interruptible_lock_irq_timeout ret: -512 signal_pending: 1 loop count: 3
    [ 4951.921944] wait_event_interruptible_lock_irq_timeout ret: -512 signal_pending: 1 loop count: 4
    [ 4951.921944] wait_event_interruptible_lock_irq_timeout ret: -512 signal_pending: 1 loop count: 5
    [ 4951.921944] wait_event_interruptible_lock_irq_timeout ret: -512 signal_pending: 1 loop count: 6
    [ 4951.921944] wait_event_interruptible_lock_irq_timeout ret: -512 signal_pending: 1 loop count: 7
    [ 4951.921944] wait_event_interruptible_lock_irq_timeout ret: -512 signal_pending: 1 loop count: 8
    [ 4951.921944] wait_event_interruptible_lock_irq_timeout ret: -512 signal_pending: 1 loop count: 9
    
    ... followed by the usual RCU CPU stalls and deadlock.
    
    There was never a case pre commit 00d909a1 where
    wait_for_complete(&se_cmd->cmd_wait_comp) was able to be interrupted, so to
    address this for v4.19+ moving forward go ahead and use
    wait_event_lock_irq_timeout() instead so new code works with all fabric
    drivers.
    
    Also for commit 00d909a1, fix a minor regression in
    target_release_cmd_kref() to only wake_up the new se_sess->cmd_list_wq only
    when shutdown has actually been triggered via se_sess->sess_tearing_down.
    
    Fixes: 00d909a1 ("scsi: target: Make the session shutdown code also wait for commands that are being aborted")
    Cc: <stable@vger.kernel.org> # v4.19+
    Cc: Bart Van Assche <bvanassche@acm.org>
    Cc: Mike Christie <mchristi@redhat.com>
    Cc: Hannes Reinecke <hare@suse.com>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Sagi Grimberg <sagi@grimberg.me>
    Cc: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
    Tested-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
    Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
    Reviewed-by: default avatarBryant G. Ly <bly@catalogicsoftware.com>
    Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
    38fe73cc
target_core_transport.c 94.9 KB