aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_target.c
diff options
context:
space:
mode:
authorQuinn Tran <quinn.tran@qlogic.com>2015-12-07 19:48:57 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2016-01-29 22:30:00 -0500
commita07100e00ac42a4474530ce17b4978c9e06bde55 (patch)
treea2f1bff160a62463533cf177c3b126737b46dbe5 /drivers/scsi/qla2xxx/qla_target.c
parentdacb58221805bb72ec46a73826c9e59a587d7d68 (diff)
qla2xxx: Fix TMR ABORT interaction issue between qla2xxx and TCM
During lun reset, TMR thread from TCM would issue abort to qla driver. At abort time, each command is in different state. Depending on the state, qla will use the TMR thread to trigger a command free(cmd_kref--) if command is not down at firmware. Signed-off-by: Quinn Tran <quinn.tran@qlogic.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com> Cc: stable@vger.kernel.org # 3.10+ Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_target.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 2c71305d2563..74eb776d2faa 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -105,7 +105,7 @@ static void qlt_response_pkt(struct scsi_qla_host *ha, response_t *pkt);
105static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun, 105static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
106 int fn, void *iocb, int flags); 106 int fn, void *iocb, int flags);
107static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd 107static void qlt_send_term_exchange(struct scsi_qla_host *ha, struct qla_tgt_cmd
108 *cmd, struct atio_from_isp *atio, int ha_locked); 108 *cmd, struct atio_from_isp *atio, int ha_locked, int ul_abort);
109static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha, 109static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha,
110 struct qla_tgt_srr_imm *imm, int ha_lock); 110 struct qla_tgt_srr_imm *imm, int ha_lock);
111static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha, 111static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha,
@@ -2665,7 +2665,7 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
2665 /* no need to terminate. FW already freed exchange. */ 2665 /* no need to terminate. FW already freed exchange. */
2666 qlt_abort_cmd_on_host_reset(cmd->vha, cmd); 2666 qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
2667 else 2667 else
2668 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1); 2668 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
2669 spin_unlock_irqrestore(&ha->hardware_lock, flags); 2669 spin_unlock_irqrestore(&ha->hardware_lock, flags);
2670 return 0; 2670 return 0;
2671 } 2671 }
@@ -3173,7 +3173,8 @@ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
3173} 3173}
3174 3174
3175static void qlt_send_term_exchange(struct scsi_qla_host *vha, 3175static void qlt_send_term_exchange(struct scsi_qla_host *vha,
3176 struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked) 3176 struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked,
3177 int ul_abort)
3177{ 3178{
3178 unsigned long flags = 0; 3179 unsigned long flags = 0;
3179 int rc; 3180 int rc;
@@ -3193,8 +3194,7 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha,
3193 qlt_alloc_qfull_cmd(vha, atio, 0, 0); 3194 qlt_alloc_qfull_cmd(vha, atio, 0, 0);
3194 3195
3195done: 3196done:
3196 if (cmd && (!cmd->aborted || 3197 if (cmd && !ul_abort && !cmd->aborted) {
3197 !cmd->cmd_sent_to_fw)) {
3198 if (cmd->sg_mapped) 3198 if (cmd->sg_mapped)
3199 qlt_unmap_sg(vha, cmd); 3199 qlt_unmap_sg(vha, cmd);
3200 vha->hw->tgt.tgt_ops->free_cmd(cmd); 3200 vha->hw->tgt.tgt_ops->free_cmd(cmd);
@@ -3253,21 +3253,38 @@ static void qlt_chk_exch_leak_thresh_hold(struct scsi_qla_host *vha)
3253 3253
3254} 3254}
3255 3255
3256void qlt_abort_cmd(struct qla_tgt_cmd *cmd) 3256int qlt_abort_cmd(struct qla_tgt_cmd *cmd)
3257{ 3257{
3258 struct qla_tgt *tgt = cmd->tgt; 3258 struct qla_tgt *tgt = cmd->tgt;
3259 struct scsi_qla_host *vha = tgt->vha; 3259 struct scsi_qla_host *vha = tgt->vha;
3260 struct se_cmd *se_cmd = &cmd->se_cmd; 3260 struct se_cmd *se_cmd = &cmd->se_cmd;
3261 unsigned long flags;
3261 3262
3262 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014, 3263 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014,
3263 "qla_target(%d): terminating exchange for aborted cmd=%p " 3264 "qla_target(%d): terminating exchange for aborted cmd=%p "
3264 "(se_cmd=%p, tag=%llu)", vha->vp_idx, cmd, &cmd->se_cmd, 3265 "(se_cmd=%p, tag=%llu)", vha->vp_idx, cmd, &cmd->se_cmd,
3265 se_cmd->tag); 3266 se_cmd->tag);
3266 3267
3268 spin_lock_irqsave(&cmd->cmd_lock, flags);
3269 if (cmd->aborted) {
3270 spin_unlock_irqrestore(&cmd->cmd_lock, flags);
3271 /*
3272 * It's normal to see 2 calls in this path:
3273 * 1) XFER Rdy completion + CMD_T_ABORT
3274 * 2) TCM TMR - drain_state_list
3275 */
3276 ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
3277 "multiple abort. %p transport_state %x, t_state %x,"
3278 " se_cmd_flags %x \n", cmd, cmd->se_cmd.transport_state,
3279 cmd->se_cmd.t_state,cmd->se_cmd.se_cmd_flags);
3280 return EIO;
3281 }
3267 cmd->aborted = 1; 3282 cmd->aborted = 1;
3268 cmd->cmd_flags |= BIT_6; 3283 cmd->cmd_flags |= BIT_6;
3284 spin_unlock_irqrestore(&cmd->cmd_lock, flags);
3269 3285
3270 qlt_send_term_exchange(vha, cmd, &cmd->atio, 0); 3286 qlt_send_term_exchange(vha, cmd, &cmd->atio, 0, 1);
3287 return 0;
3271} 3288}
3272EXPORT_SYMBOL(qlt_abort_cmd); 3289EXPORT_SYMBOL(qlt_abort_cmd);
3273 3290
@@ -3282,6 +3299,9 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
3282 3299
3283 BUG_ON(cmd->cmd_in_wq); 3300 BUG_ON(cmd->cmd_in_wq);
3284 3301
3302 if (cmd->sg_mapped)
3303 qlt_unmap_sg(cmd->vha, cmd);
3304
3285 if (!cmd->q_full) 3305 if (!cmd->q_full)
3286 qlt_decr_num_pend_cmds(cmd->vha); 3306 qlt_decr_num_pend_cmds(cmd->vha);
3287 3307
@@ -3399,7 +3419,7 @@ static int qlt_term_ctio_exchange(struct scsi_qla_host *vha, void *ctio,
3399 term = 1; 3419 term = 1;
3400 3420
3401 if (term) 3421 if (term)
3402 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1); 3422 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
3403 3423
3404 return term; 3424 return term;
3405} 3425}
@@ -3755,6 +3775,7 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
3755 goto out_term; 3775 goto out_term;
3756 } 3776 }
3757 3777
3778 spin_lock_init(&cmd->cmd_lock);
3758 cdb = &atio->u.isp24.fcp_cmnd.cdb[0]; 3779 cdb = &atio->u.isp24.fcp_cmnd.cdb[0];
3759 cmd->se_cmd.tag = atio->u.isp24.exchange_addr; 3780 cmd->se_cmd.tag = atio->u.isp24.exchange_addr;
3760 cmd->unpacked_lun = scsilun_to_int( 3781 cmd->unpacked_lun = scsilun_to_int(
@@ -3797,7 +3818,7 @@ out_term:
3797 */ 3818 */
3798 cmd->cmd_flags |= BIT_2; 3819 cmd->cmd_flags |= BIT_2;
3799 spin_lock_irqsave(&ha->hardware_lock, flags); 3820 spin_lock_irqsave(&ha->hardware_lock, flags);
3800 qlt_send_term_exchange(vha, NULL, &cmd->atio, 1); 3821 qlt_send_term_exchange(vha, NULL, &cmd->atio, 1, 0);
3801 3822
3802 qlt_decr_num_pend_cmds(vha); 3823 qlt_decr_num_pend_cmds(vha);
3803 percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag); 3824 percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag);
@@ -3919,7 +3940,7 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
3919 3940
3920out_term: 3941out_term:
3921 spin_lock_irqsave(&ha->hardware_lock, flags); 3942 spin_lock_irqsave(&ha->hardware_lock, flags);
3922 qlt_send_term_exchange(vha, NULL, &op->atio, 1); 3943 qlt_send_term_exchange(vha, NULL, &op->atio, 1, 0);
3923 spin_unlock_irqrestore(&ha->hardware_lock, flags); 3944 spin_unlock_irqrestore(&ha->hardware_lock, flags);
3924 kfree(op); 3945 kfree(op);
3925 3946
@@ -4772,7 +4793,7 @@ out_reject:
4772 dump_stack(); 4793 dump_stack();
4773 } else { 4794 } else {
4774 cmd->cmd_flags |= BIT_9; 4795 cmd->cmd_flags |= BIT_9;
4775 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1); 4796 qlt_send_term_exchange(vha, cmd, &cmd->atio, 1, 0);
4776 } 4797 }
4777 spin_unlock_irqrestore(&ha->hardware_lock, flags); 4798 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4778} 4799}
@@ -4951,7 +4972,7 @@ static void qlt_prepare_srr_imm(struct scsi_qla_host *vha,
4951 sctio, sctio->srr_id); 4972 sctio, sctio->srr_id);
4952 list_del(&sctio->srr_list_entry); 4973 list_del(&sctio->srr_list_entry);
4953 qlt_send_term_exchange(vha, sctio->cmd, 4974 qlt_send_term_exchange(vha, sctio->cmd,
4954 &sctio->cmd->atio, 1); 4975 &sctio->cmd->atio, 1, 0);
4955 kfree(sctio); 4976 kfree(sctio);
4956 } 4977 }
4957 } 4978 }
@@ -5124,7 +5145,7 @@ static int __qlt_send_busy(struct scsi_qla_host *vha,
5124 atio->u.isp24.fcp_hdr.s_id); 5145 atio->u.isp24.fcp_hdr.s_id);
5125 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 5146 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
5126 if (!sess) { 5147 if (!sess) {
5127 qlt_send_term_exchange(vha, NULL, atio, 1); 5148 qlt_send_term_exchange(vha, NULL, atio, 1, 0);
5128 return 0; 5149 return 0;
5129 } 5150 }
5130 /* Sending marker isn't necessary, since we called from ISR */ 5151 /* Sending marker isn't necessary, since we called from ISR */
@@ -5407,7 +5428,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
5407#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ 5428#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
5408 qlt_send_busy(vha, atio, SAM_STAT_BUSY); 5429 qlt_send_busy(vha, atio, SAM_STAT_BUSY);
5409#else 5430#else
5410 qlt_send_term_exchange(vha, NULL, atio, 1); 5431 qlt_send_term_exchange(vha, NULL, atio, 1, 0);
5411#endif 5432#endif
5412 5433
5413 if (!ha_locked) 5434 if (!ha_locked)
@@ -5524,7 +5545,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
5524#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ 5545#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
5525 qlt_send_busy(vha, atio, 0); 5546 qlt_send_busy(vha, atio, 0);
5526#else 5547#else
5527 qlt_send_term_exchange(vha, NULL, atio, 1); 5548 qlt_send_term_exchange(vha, NULL, atio, 1, 0);
5528#endif 5549#endif
5529 } else { 5550 } else {
5530 if (tgt->tgt_stop) { 5551 if (tgt->tgt_stop) {
@@ -5533,7 +5554,7 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
5533 "command to target, sending TERM " 5554 "command to target, sending TERM "
5534 "EXCHANGE for rsp\n"); 5555 "EXCHANGE for rsp\n");
5535 qlt_send_term_exchange(vha, NULL, 5556 qlt_send_term_exchange(vha, NULL,
5536 atio, 1); 5557 atio, 1, 0);
5537 } else { 5558 } else {
5538 ql_dbg(ql_dbg_tgt, vha, 0xe060, 5559 ql_dbg(ql_dbg_tgt, vha, 0xe060,
5539 "qla_target(%d): Unable to send " 5560 "qla_target(%d): Unable to send "
@@ -5961,7 +5982,7 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
5961 return; 5982 return;
5962 5983
5963out_term: 5984out_term:
5964 qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 0); 5985 qlt_send_term_exchange(vha, NULL, &prm->tm_iocb2, 1, 0);
5965 if (sess) 5986 if (sess)
5966 ha->tgt.tgt_ops->put_sess(sess); 5987 ha->tgt.tgt_ops->put_sess(sess);
5967 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); 5988 spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);