scsi: qla2xxx: Limit TMF to 8 per function
Per FW recommendation, 8 TMF's can be outstanding for each function. Previously, it allowed 8 per target. Limit TMF to 8 per function. Cc: stable@vger.kernel.org Fixes: 6a87679626b5 ("scsi: qla2xxx: Fix task management cmd fail due to unavailable resource") Signed-off-by: Quinn Tran <qutran@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Link: https://lore.kernel.org/r/20230714070104.40052-4-njavali@marvell.com Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
efa74a62aa
commit
a8ec192427
@ -466,6 +466,7 @@ static inline be_id_t port_id_to_be_id(port_id_t port_id)
|
||||
}
|
||||
|
||||
struct tmf_arg {
|
||||
struct list_head tmf_elem;
|
||||
struct qla_qpair *qpair;
|
||||
struct fc_port *fcport;
|
||||
struct scsi_qla_host *vha;
|
||||
@ -2541,7 +2542,6 @@ enum rscn_addr_format {
|
||||
typedef struct fc_port {
|
||||
struct list_head list;
|
||||
struct scsi_qla_host *vha;
|
||||
struct list_head tmf_pending;
|
||||
|
||||
unsigned int conf_compl_supported:1;
|
||||
unsigned int deleted:2;
|
||||
@ -2562,9 +2562,6 @@ typedef struct fc_port {
|
||||
unsigned int do_prli_nvme:1;
|
||||
|
||||
uint8_t nvme_flag;
|
||||
uint8_t active_tmf;
|
||||
#define MAX_ACTIVE_TMF 8
|
||||
|
||||
uint8_t node_name[WWN_SIZE];
|
||||
uint8_t port_name[WWN_SIZE];
|
||||
port_id_t d_id;
|
||||
@ -4657,6 +4654,8 @@ struct qla_hw_data {
|
||||
uint32_t flt_region_aux_img_status_sec;
|
||||
};
|
||||
uint8_t active_image;
|
||||
uint8_t active_tmf;
|
||||
#define MAX_ACTIVE_TMF 8
|
||||
|
||||
/* Needed for BEACON */
|
||||
uint16_t beacon_blink_led;
|
||||
@ -4671,6 +4670,8 @@ struct qla_hw_data {
|
||||
|
||||
struct qla_msix_entry *msix_entries;
|
||||
|
||||
struct list_head tmf_pending;
|
||||
struct list_head tmf_active;
|
||||
struct list_head vp_list; /* list of VP */
|
||||
unsigned long vp_idx_map[(MAX_MULTI_ID_FABRIC / 8) /
|
||||
sizeof(unsigned long)];
|
||||
|
@ -2192,30 +2192,42 @@ done:
|
||||
return rval;
|
||||
}
|
||||
|
||||
static void qla_put_tmf(fc_port_t *fcport)
|
||||
static void qla_put_tmf(struct tmf_arg *arg)
|
||||
{
|
||||
struct scsi_qla_host *vha = fcport->vha;
|
||||
struct scsi_qla_host *vha = arg->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
fcport->active_tmf--;
|
||||
ha->active_tmf--;
|
||||
list_del(&arg->tmf_elem);
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
}
|
||||
|
||||
static
|
||||
int qla_get_tmf(fc_port_t *fcport)
|
||||
int qla_get_tmf(struct tmf_arg *arg)
|
||||
{
|
||||
struct scsi_qla_host *vha = fcport->vha;
|
||||
struct scsi_qla_host *vha = arg->vha;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
unsigned long flags;
|
||||
fc_port_t *fcport = arg->fcport;
|
||||
int rc = 0;
|
||||
LIST_HEAD(tmf_elem);
|
||||
struct tmf_arg *t;
|
||||
|
||||
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
|
||||
list_add_tail(&tmf_elem, &fcport->tmf_pending);
|
||||
list_for_each_entry(t, &ha->tmf_active, tmf_elem) {
|
||||
if (t->fcport == arg->fcport && t->lun == arg->lun) {
|
||||
/* reject duplicate TMF */
|
||||
ql_log(ql_log_warn, vha, 0x802c,
|
||||
"found duplicate TMF. Nexus=%ld:%06x:%llu.\n",
|
||||
vha->host_no, fcport->d_id.b24, arg->lun);
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
while (fcport->active_tmf >= MAX_ACTIVE_TMF) {
|
||||
list_add_tail(&arg->tmf_elem, &ha->tmf_pending);
|
||||
while (ha->active_tmf >= MAX_ACTIVE_TMF) {
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
|
||||
msleep(1);
|
||||
@ -2227,15 +2239,17 @@ int qla_get_tmf(fc_port_t *fcport)
|
||||
rc = EIO;
|
||||
break;
|
||||
}
|
||||
if (fcport->active_tmf < MAX_ACTIVE_TMF &&
|
||||
list_is_first(&tmf_elem, &fcport->tmf_pending))
|
||||
if (ha->active_tmf < MAX_ACTIVE_TMF &&
|
||||
list_is_first(&arg->tmf_elem, &ha->tmf_pending))
|
||||
break;
|
||||
}
|
||||
|
||||
list_del(&tmf_elem);
|
||||
list_del(&arg->tmf_elem);
|
||||
|
||||
if (!rc)
|
||||
fcport->active_tmf++;
|
||||
if (!rc) {
|
||||
ha->active_tmf++;
|
||||
list_add_tail(&arg->tmf_elem, &ha->tmf_active);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
|
||||
|
||||
@ -2257,15 +2271,18 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
|
||||
a.vha = fcport->vha;
|
||||
a.fcport = fcport;
|
||||
a.lun = lun;
|
||||
a.flags = flags;
|
||||
INIT_LIST_HEAD(&a.tmf_elem);
|
||||
|
||||
if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) {
|
||||
a.modifier = MK_SYNC_ID_LUN;
|
||||
|
||||
if (qla_get_tmf(fcport))
|
||||
return QLA_FUNCTION_FAILED;
|
||||
} else {
|
||||
a.modifier = MK_SYNC_ID;
|
||||
}
|
||||
|
||||
if (qla_get_tmf(&a))
|
||||
return QLA_FUNCTION_FAILED;
|
||||
|
||||
if (vha->hw->mqenable) {
|
||||
for (i = 0; i < vha->hw->num_qpairs; i++) {
|
||||
qpair = vha->hw->queue_pair_map[i];
|
||||
@ -2291,13 +2308,10 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
|
||||
goto bailout;
|
||||
|
||||
a.qpair = vha->hw->base_qpair;
|
||||
a.flags = flags;
|
||||
rval = __qla2x00_async_tm_cmd(&a);
|
||||
|
||||
bailout:
|
||||
if (a.modifier == MK_SYNC_ID_LUN)
|
||||
qla_put_tmf(fcport);
|
||||
|
||||
qla_put_tmf(&a);
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -5526,7 +5540,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
|
||||
INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
|
||||
INIT_LIST_HEAD(&fcport->gnl_entry);
|
||||
INIT_LIST_HEAD(&fcport->list);
|
||||
INIT_LIST_HEAD(&fcport->tmf_pending);
|
||||
|
||||
INIT_LIST_HEAD(&fcport->sess_cmd_list);
|
||||
spin_lock_init(&fcport->sess_cmd_lock);
|
||||
|
@ -3009,6 +3009,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
atomic_set(&ha->num_pend_mbx_stage3, 0);
|
||||
atomic_set(&ha->zio_threshold, DEFAULT_ZIO_THRESHOLD);
|
||||
ha->last_zio_threshold = DEFAULT_ZIO_THRESHOLD;
|
||||
INIT_LIST_HEAD(&ha->tmf_pending);
|
||||
INIT_LIST_HEAD(&ha->tmf_active);
|
||||
|
||||
/* Assign ISP specific operations. */
|
||||
if (IS_QLA2100(ha)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user