• Nicholas Bellinger's avatar
    target: Fix missing complete during ABORT_TASK + CMD_T_FABRIC_STOP · 5e2c956b
    Nicholas Bellinger authored
    During transport_generic_free_cmd() with a concurrent TMR
    ABORT_TASK and shutdown CMD_T_FABRIC_STOP bit set, the
    caller will be blocked on se_cmd->cmd_wait_stop completion
    until the final kref_put() -> target_release_cmd_kref()
    has been invoked to call complete().
    
    However, when ABORT_TASK is completed with FUNCTION_COMPLETE
    in core_tmr_abort_task(), the aborted se_cmd will have already
    been removed from se_sess->sess_cmd_list via list_del_init().
    
    This results in target_release_cmd_kref() hitting the
    legacy list_empty() == true check, invoking ->release_cmd()
    but skipping complete() to wakeup se_cmd->cmd_wait_stop
    blocked earlier in transport_generic_free_cmd() code.
    
    To address this bug, it's safe to go ahead and drop the
    original list_empty() check so that fabric_stop invokes
    the complete() as expected, since list_del_init() can
    safely be used on a empty list.
    
    Cc: Mike Christie <mchristi@redhat.com>
    Cc: Quinn Tran <quinn.tran@qlogic.com>
    Cc: Himanshu Madhani <himanshu.madhani@qlogic.com>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Hannes Reinecke <hare@suse.de>
    Cc: stable@vger.kernel.org # 3.14+
    Tested-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
    Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
    5e2c956b
target_core_transport.c 82.9 KB