diff options
author | Alexei Potashnik <alexei@purestorage.com> | 2015-07-14 16:00:45 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-07-24 17:19:40 -0400 |
commit | daddf5cf9b5c68b81b2bb7133f1dd0fda4552d0b (patch) | |
tree | d3b32ada3272b5792d890eebfd82c65e41190a57 | |
parent | a6ca88780dd66b0700d89419abd17b6b4bb49483 (diff) |
qla2xxx: Abort stale cmds on qla_tgt_wq when plogi arrives
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>
-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 acb2a50d3c55..0b08bebea538 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -4060,6 +4060,38 @@ qlt_find_sess_invalidate_other(struct qla_tgt *tgt, uint64_t wwn, | |||
4060 | return sess; | 4060 | return sess; |
4061 | } | 4061 | } |
4062 | 4062 | ||
4063 | /* Abort any commands for this s_id waiting on qla_tgt_wq workqueue */ | ||
4064 | static int abort_cmds_for_s_id(struct scsi_qla_host *vha, port_id_t *s_id) | ||
4065 | { | ||
4066 | struct qla_tgt_sess_op *op; | ||
4067 | struct qla_tgt_cmd *cmd; | ||
4068 | uint32_t key; | ||
4069 | int count = 0; | ||
4070 | |||
4071 | key = (((u32)s_id->b.domain << 16) | | ||
4072 | ((u32)s_id->b.area << 8) | | ||
4073 | ((u32)s_id->b.al_pa)); | ||
4074 | |||
4075 | spin_lock(&vha->cmd_list_lock); | ||
4076 | list_for_each_entry(op, &vha->qla_sess_op_cmd_list, cmd_list) { | ||
4077 | uint32_t op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id); | ||
4078 | if (op_key == key) { | ||
4079 | op->aborted = true; | ||
4080 | count++; | ||
4081 | } | ||
4082 | } | ||
4083 | list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) { | ||
4084 | uint32_t cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id); | ||
4085 | if (cmd_key == key) { | ||
4086 | cmd->state = QLA_TGT_STATE_ABORTED; | ||
4087 | count++; | ||
4088 | } | ||
4089 | } | ||
4090 | spin_unlock(&vha->cmd_list_lock); | ||
4091 | |||
4092 | return count; | ||
4093 | } | ||
4094 | |||
4063 | /* | 4095 | /* |
4064 | * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire | 4096 | * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire |
4065 | */ | 4097 | */ |
@@ -4093,6 +4125,9 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, | |||
4093 | switch (iocb->u.isp24.status_subcode) { | 4125 | switch (iocb->u.isp24.status_subcode) { |
4094 | case ELS_PLOGI: | 4126 | case ELS_PLOGI: |
4095 | 4127 | ||
4128 | /* Mark all stale commands in qla_tgt_wq for deletion */ | ||
4129 | abort_cmds_for_s_id(vha, &port_id); | ||
4130 | |||
4096 | if (wwn) | 4131 | if (wwn) |
4097 | sess = qlt_find_sess_invalidate_other(tgt, wwn, | 4132 | sess = qlt_find_sess_invalidate_other(tgt, wwn, |
4098 | port_id, loop_id); | 4133 | port_id, loop_id); |