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: Quinn Tran <quinn.tran@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
9d1aa4e14e
commit
7cf95f7e01
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
"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,
|
|||||||
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,
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||||
flags);
|
switch (rc) {
|
||||||
|
case -ENODEV:
|
||||||
#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
|
ql_dbg(ql_dbg_tgt, vha, 0xe05f,
|
||||||
qlt_send_busy(ha->base_qpair, atio,
|
"qla_target: Unable to send command to target\n");
|
||||||
SAM_STAT_BUSY);
|
break;
|
||||||
#else
|
case -EBADF:
|
||||||
|
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,
|
|||||||
|
|
||||||
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);
|
|
||||||
#else
|
|
||||||
qlt_send_term_exchange(rsp->qpair, NULL, atio, 1, 0);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
if (tgt->tgt_stop) {
|
|
||||||
ql_dbg(ql_dbg_tgt, vha, 0xe05f,
|
ql_dbg(ql_dbg_tgt, vha, 0xe05f,
|
||||||
"qla_target: Unable to send "
|
"qla_target: Unable to send command to target\n");
|
||||||
"command to target, sending TERM "
|
break;
|
||||||
"EXCHANGE for rsp\n");
|
case -EBADF:
|
||||||
|
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(rsp->qpair, NULL,
|
qlt_send_term_exchange(rsp->qpair, NULL,
|
||||||
atio, 1, 0);
|
atio, 1, 0);
|
||||||
} else {
|
break;
|
||||||
|
case -EBUSY:
|
||||||
ql_dbg(ql_dbg_tgt, vha, 0xe060,
|
ql_dbg(ql_dbg_tgt, vha, 0xe060,
|
||||||
"qla_target(%d): Unable to send "
|
"qla_target(%d): Unable to send command to target, sending BUSY status\n",
|
||||||
"command to target, sending BUSY "
|
vha->vp_idx);
|
||||||
"status\n", vha->vp_idx);
|
qlt_send_busy(rsp->qpair, atio,
|
||||||
qlt_send_busy(rsp->qpair, atio, 0);
|
tc_sam_status);
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user