Commit 7cf95f7e authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen

scsi: qla2xxx: Reduce the use of terminate exchange

reduce usage of terminate exchange when command encounter
resource bottle neck.  Remote initiator view it as command
drop.
Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 9d1aa4e1
...@@ -75,7 +75,8 @@ MODULE_PARM_DESC(ql2xuctrlirq, ...@@ -75,7 +75,8 @@ MODULE_PARM_DESC(ql2xuctrlirq,
int ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE; int ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE;
static int temp_sam_status = SAM_STAT_BUSY; static int qla_sam_status = SAM_STAT_BUSY;
static int tc_sam_status = SAM_STAT_TASK_SET_FULL; /* target core */
/* /*
* From scsi/fc/fc_fcp.h * From scsi/fc/fc_fcp.h
...@@ -4275,14 +4276,14 @@ static void qlt_create_sess_from_atio(struct work_struct *work) ...@@ -4275,14 +4276,14 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
if (op->atio.u.raw.entry_count > 1) { if (op->atio.u.raw.entry_count > 1) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf023, ql_dbg(ql_dbg_tgt_mgt, vha, 0xf023,
"Dropping multy entry atio %p\n", &op->atio); "Dropping multy entry atio %p\n", &op->atio);
goto out_term; goto out_busy;
} }
sess = qlt_make_local_sess(vha, s_id); sess = qlt_make_local_sess(vha, s_id);
/* sess has an extra creation ref. */ /* sess has an extra creation ref. */
if (!sess) if (!sess)
goto out_term; goto out_busy;
/* /*
* Now obtain a pre-allocated session tag using the original op->atio * Now obtain a pre-allocated session tag using the original op->atio
* packet header, and dispatch into __qlt_do_work() using the existing * packet header, and dispatch into __qlt_do_work() using the existing
...@@ -4293,7 +4294,7 @@ static void qlt_create_sess_from_atio(struct work_struct *work) ...@@ -4293,7 +4294,7 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
struct qla_qpair *qpair = ha->base_qpair; struct qla_qpair *qpair = ha->base_qpair;
spin_lock_irqsave(qpair->qp_lock_ptr, flags); spin_lock_irqsave(qpair->qp_lock_ptr, flags);
qlt_send_busy(qpair, &op->atio, SAM_STAT_BUSY); qlt_send_busy(qpair, &op->atio, tc_sam_status);
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
spin_lock_irqsave(&ha->tgt.sess_lock, flags); spin_lock_irqsave(&ha->tgt.sess_lock, flags);
...@@ -4313,6 +4314,17 @@ static void qlt_create_sess_from_atio(struct work_struct *work) ...@@ -4313,6 +4314,17 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
out_term: out_term:
qlt_send_term_exchange(vha->hw->base_qpair, NULL, &op->atio, 0, 0); qlt_send_term_exchange(vha->hw->base_qpair, NULL, &op->atio, 0, 0);
kfree(op); kfree(op);
return;
out_busy:
{
struct qla_qpair *qpair = ha->base_qpair;
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
qlt_send_busy(qpair, &op->atio, qla_sam_status);
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
kfree(op);
}
return;
} }
/* ha->hardware_lock supposed to be held on entry */ /* ha->hardware_lock supposed to be held on entry */
...@@ -4329,7 +4341,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, ...@@ -4329,7 +4341,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
if (unlikely(tgt->tgt_stop)) { if (unlikely(tgt->tgt_stop)) {
ql_dbg(ql_dbg_io, vha, 0x3061, ql_dbg(ql_dbg_io, vha, 0x3061,
"New command while device %p is shutting down\n", tgt); "New command while device %p is shutting down\n", tgt);
return -EFAULT; return -ENODEV;
} }
id.b.al_pa = atio->u.isp24.fcp_hdr.s_id[2]; id.b.al_pa = atio->u.isp24.fcp_hdr.s_id[2];
...@@ -4384,7 +4396,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, ...@@ -4384,7 +4396,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
spin_lock_irqsave(&ha->tgt.sess_lock, flags); spin_lock_irqsave(&ha->tgt.sess_lock, flags);
ha->tgt.tgt_ops->put_sess(sess); ha->tgt.tgt_ops->put_sess(sess);
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
return -ENOMEM; return -EBUSY;
} }
cmd->cmd_in_wq = 1; cmd->cmd_in_wq = 1;
...@@ -5485,7 +5497,6 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, struct qla_qpair *qpair, ...@@ -5485,7 +5497,6 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, struct qla_qpair *qpair,
struct atio_from_isp *atio, uint8_t ha_locked) struct atio_from_isp *atio, uint8_t ha_locked)
{ {
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
uint16_t status;
unsigned long flags; unsigned long flags;
if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha)) if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha))
...@@ -5493,8 +5504,7 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, struct qla_qpair *qpair, ...@@ -5493,8 +5504,7 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, struct qla_qpair *qpair,
if (!ha_locked) if (!ha_locked)
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
status = temp_sam_status; qlt_send_busy(qpair, atio, qla_sam_status);
qlt_send_busy(qpair, atio, status);
if (!ha_locked) if (!ha_locked)
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
...@@ -5509,7 +5519,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, ...@@ -5509,7 +5519,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
int rc; int rc;
unsigned long flags; unsigned long flags = 0;
if (unlikely(tgt == NULL)) { if (unlikely(tgt == NULL)) {
ql_dbg(ql_dbg_tgt, vha, 0x3064, ql_dbg(ql_dbg_tgt, vha, 0x3064,
...@@ -5533,8 +5543,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, ...@@ -5533,8 +5543,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
"sending QUEUE_FULL\n", vha->vp_idx); "sending QUEUE_FULL\n", vha->vp_idx);
if (!ha_locked) if (!ha_locked)
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
qlt_send_busy(ha->base_qpair, atio, qlt_send_busy(ha->base_qpair, atio, qla_sam_status);
SAM_STAT_TASK_SET_FULL);
if (!ha_locked) if (!ha_locked)
spin_unlock_irqrestore(&ha->hardware_lock, spin_unlock_irqrestore(&ha->hardware_lock,
flags); flags);
...@@ -5553,42 +5562,37 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, ...@@ -5553,42 +5562,37 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
rc = qlt_handle_task_mgmt(vha, atio); rc = qlt_handle_task_mgmt(vha, atio);
} }
if (unlikely(rc != 0)) { if (unlikely(rc != 0)) {
if (rc == -ESRCH) { if (!ha_locked)
if (!ha_locked) spin_lock_irqsave(&ha->hardware_lock, flags);
spin_lock_irqsave(&ha->hardware_lock, switch (rc) {
flags); case -ENODEV:
ql_dbg(ql_dbg_tgt, vha, 0xe05f,
#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ "qla_target: Unable to send command to target\n");
qlt_send_busy(ha->base_qpair, atio, break;
SAM_STAT_BUSY); case -EBADF:
#else ql_dbg(ql_dbg_tgt, vha, 0xe05f,
"qla_target: Unable to send command to target, sending TERM EXCHANGE for rsp\n");
qlt_send_term_exchange(ha->base_qpair, NULL, qlt_send_term_exchange(ha->base_qpair, NULL,
atio, 1, 0); atio, 1, 0);
#endif break;
if (!ha_locked) case -EBUSY:
spin_unlock_irqrestore( ql_dbg(ql_dbg_tgt, vha, 0xe060,
&ha->hardware_lock, flags); "qla_target(%d): Unable to send command to target, sending BUSY status\n",
} else { vha->vp_idx);
if (tgt->tgt_stop) { qlt_send_busy(ha->base_qpair, atio,
ql_dbg(ql_dbg_tgt, vha, 0xe059, tc_sam_status);
"qla_target: Unable to send " break;
"command to target for req, " default:
"ignoring.\n"); ql_dbg(ql_dbg_tgt, vha, 0xe060,
} else { "qla_target(%d): Unable to send command to target, sending BUSY status\n",
ql_dbg(ql_dbg_tgt, vha, 0xe05a, vha->vp_idx);
"qla_target(%d): Unable to send " qlt_send_busy(ha->base_qpair, atio,
"command to target, sending BUSY " qla_sam_status);
"status.\n", vha->vp_idx); break;
if (!ha_locked)
spin_lock_irqsave(
&ha->hardware_lock, flags);
qlt_send_busy(ha->base_qpair,
atio, SAM_STAT_BUSY);
if (!ha_locked)
spin_unlock_irqrestore(
&ha->hardware_lock, flags);
}
} }
if (!ha_locked)
spin_unlock_irqrestore(&ha->hardware_lock,
flags);
} }
break; break;
...@@ -5671,27 +5675,31 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, ...@@ -5671,27 +5675,31 @@ static void qlt_response_pkt(struct scsi_qla_host *vha,
rc = qlt_handle_cmd_for_atio(vha, atio); rc = qlt_handle_cmd_for_atio(vha, atio);
if (unlikely(rc != 0)) { if (unlikely(rc != 0)) {
if (rc == -ESRCH) { switch (rc) {
#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */ case -ENODEV:
qlt_send_busy(rsp->qpair, atio, 0); ql_dbg(ql_dbg_tgt, vha, 0xe05f,
#else "qla_target: Unable to send command to target\n");
qlt_send_term_exchange(rsp->qpair, NULL, atio, 1, 0); break;
#endif case -EBADF:
} else { ql_dbg(ql_dbg_tgt, vha, 0xe05f,
if (tgt->tgt_stop) { "qla_target: Unable to send command to target, sending TERM EXCHANGE for rsp\n");
ql_dbg(ql_dbg_tgt, vha, 0xe05f, qlt_send_term_exchange(rsp->qpair, NULL,
"qla_target: Unable to send " atio, 1, 0);
"command to target, sending TERM " break;
"EXCHANGE for rsp\n"); case -EBUSY:
qlt_send_term_exchange(rsp->qpair, NULL, ql_dbg(ql_dbg_tgt, vha, 0xe060,
atio, 1, 0); "qla_target(%d): Unable to send command to target, sending BUSY status\n",
} else { vha->vp_idx);
ql_dbg(ql_dbg_tgt, vha, 0xe060, qlt_send_busy(rsp->qpair, atio,
"qla_target(%d): Unable to send " tc_sam_status);
"command to target, sending BUSY " break;
"status\n", vha->vp_idx); default:
qlt_send_busy(rsp->qpair, atio, 0); ql_dbg(ql_dbg_tgt, vha, 0xe060,
} "qla_target(%d): Unable to send command to target, sending BUSY status\n",
vha->vp_idx);
qlt_send_busy(rsp->qpair, atio,
qla_sam_status);
break;
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment