diff options
author | Alexei Potashnik <alexei@purestorage.com> | 2015-07-14 16:00:45 -0400 |
---|---|---|
committer | Sasha Levin <sasha.levin@oracle.com> | 2016-03-02 15:18:51 -0500 |
commit | 547a00fa032c6fd8fe7ad0bf67b7af0e9f0ee1b6 (patch) | |
tree | 5041c53d8c1cefce1b6989a8e5fa4b3e45588e52 /drivers/scsi/qla2xxx | |
parent | 79710b5014915240d1f1015cc5fa27db4bbd898b (diff) | |
download | linux-rt-547a00fa032c6fd8fe7ad0bf67b7af0e9f0ee1b6.tar.gz |
qla2xxx: Abort stale cmds on qla_tgt_wq when plogi arrives
[ Upstream commit daddf5cf9b5c68b81b2bb7133f1dd0fda4552d0b ]
cancel any commands from initiator's s_id that are still waiting
on qla_tgt_wq when PLOGI arrives.
Cc: <stable@vger.kernel.org> # v3.18+
Signed-off-by: Alexei Potashnik <alexei@purestorage.com>
Acked-by: Quinn Tran <quinn.tran@qlogic.com>
Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Diffstat (limited to 'drivers/scsi/qla2xxx')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 2ee4b6475b6e..a5b3071142ce 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -4080,6 +4080,38 @@ qlt_find_sess_invalidate_other(struct qla_tgt *tgt, uint64_t wwn, return sess; } +/* Abort any commands for this s_id waiting on qla_tgt_wq workqueue */ +static int abort_cmds_for_s_id(struct scsi_qla_host *vha, port_id_t *s_id) +{ + struct qla_tgt_sess_op *op; + struct qla_tgt_cmd *cmd; + uint32_t key; + int count = 0; + + key = (((u32)s_id->b.domain << 16) | + ((u32)s_id->b.area << 8) | + ((u32)s_id->b.al_pa)); + + spin_lock(&vha->cmd_list_lock); + list_for_each_entry(op, &vha->qla_sess_op_cmd_list, cmd_list) { + uint32_t op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id); + if (op_key == key) { + op->aborted = true; + count++; + } + } + list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) { + uint32_t cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id); + if (cmd_key == key) { + cmd->state = QLA_TGT_STATE_ABORTED; + count++; + } + } + spin_unlock(&vha->cmd_list_lock); + + return count; +} + /* * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire */ @@ -4113,6 +4145,9 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, switch (iocb->u.isp24.status_subcode) { case ELS_PLOGI: + /* Mark all stale commands in qla_tgt_wq for deletion */ + abort_cmds_for_s_id(vha, &port_id); + if (wwn) sess = qlt_find_sess_invalidate_other(tgt, wwn, port_id, loop_id); |