Skip to content

Commit a8ec192

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
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: 6a87679 ("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>
1 parent efa74a6 commit a8ec192

File tree

3 files changed

+41
-25
lines changed

3 files changed

+41
-25
lines changed

drivers/scsi/qla2xxx/qla_def.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ static inline be_id_t port_id_to_be_id(port_id_t port_id)
466466
}
467467

468468
struct tmf_arg {
469+
struct list_head tmf_elem;
469470
struct qla_qpair *qpair;
470471
struct fc_port *fcport;
471472
struct scsi_qla_host *vha;
@@ -2541,7 +2542,6 @@ enum rscn_addr_format {
25412542
typedef struct fc_port {
25422543
struct list_head list;
25432544
struct scsi_qla_host *vha;
2544-
struct list_head tmf_pending;
25452545

25462546
unsigned int conf_compl_supported:1;
25472547
unsigned int deleted:2;
@@ -2562,9 +2562,6 @@ typedef struct fc_port {
25622562
unsigned int do_prli_nvme:1;
25632563

25642564
uint8_t nvme_flag;
2565-
uint8_t active_tmf;
2566-
#define MAX_ACTIVE_TMF 8
2567-
25682565
uint8_t node_name[WWN_SIZE];
25692566
uint8_t port_name[WWN_SIZE];
25702567
port_id_t d_id;
@@ -4657,6 +4654,8 @@ struct qla_hw_data {
46574654
uint32_t flt_region_aux_img_status_sec;
46584655
};
46594656
uint8_t active_image;
4657+
uint8_t active_tmf;
4658+
#define MAX_ACTIVE_TMF 8
46604659

46614660
/* Needed for BEACON */
46624661
uint16_t beacon_blink_led;
@@ -4671,6 +4670,8 @@ struct qla_hw_data {
46714670

46724671
struct qla_msix_entry *msix_entries;
46734672

4673+
struct list_head tmf_pending;
4674+
struct list_head tmf_active;
46744675
struct list_head vp_list; /* list of VP */
46754676
unsigned long vp_idx_map[(MAX_MULTI_ID_FABRIC / 8) /
46764677
sizeof(unsigned long)];

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2192,30 +2192,42 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
21922192
return rval;
21932193
}
21942194

2195-
static void qla_put_tmf(fc_port_t *fcport)
2195+
static void qla_put_tmf(struct tmf_arg *arg)
21962196
{
2197-
struct scsi_qla_host *vha = fcport->vha;
2197+
struct scsi_qla_host *vha = arg->vha;
21982198
struct qla_hw_data *ha = vha->hw;
21992199
unsigned long flags;
22002200

22012201
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
2202-
fcport->active_tmf--;
2202+
ha->active_tmf--;
2203+
list_del(&arg->tmf_elem);
22032204
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
22042205
}
22052206

22062207
static
2207-
int qla_get_tmf(fc_port_t *fcport)
2208+
int qla_get_tmf(struct tmf_arg *arg)
22082209
{
2209-
struct scsi_qla_host *vha = fcport->vha;
2210+
struct scsi_qla_host *vha = arg->vha;
22102211
struct qla_hw_data *ha = vha->hw;
22112212
unsigned long flags;
2213+
fc_port_t *fcport = arg->fcport;
22122214
int rc = 0;
2213-
LIST_HEAD(tmf_elem);
2215+
struct tmf_arg *t;
22142216

22152217
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
2216-
list_add_tail(&tmf_elem, &fcport->tmf_pending);
2218+
list_for_each_entry(t, &ha->tmf_active, tmf_elem) {
2219+
if (t->fcport == arg->fcport && t->lun == arg->lun) {
2220+
/* reject duplicate TMF */
2221+
ql_log(ql_log_warn, vha, 0x802c,
2222+
"found duplicate TMF. Nexus=%ld:%06x:%llu.\n",
2223+
vha->host_no, fcport->d_id.b24, arg->lun);
2224+
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
2225+
return -EINVAL;
2226+
}
2227+
}
22172228

2218-
while (fcport->active_tmf >= MAX_ACTIVE_TMF) {
2229+
list_add_tail(&arg->tmf_elem, &ha->tmf_pending);
2230+
while (ha->active_tmf >= MAX_ACTIVE_TMF) {
22192231
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
22202232

22212233
msleep(1);
@@ -2227,15 +2239,17 @@ int qla_get_tmf(fc_port_t *fcport)
22272239
rc = EIO;
22282240
break;
22292241
}
2230-
if (fcport->active_tmf < MAX_ACTIVE_TMF &&
2231-
list_is_first(&tmf_elem, &fcport->tmf_pending))
2242+
if (ha->active_tmf < MAX_ACTIVE_TMF &&
2243+
list_is_first(&arg->tmf_elem, &ha->tmf_pending))
22322244
break;
22332245
}
22342246

2235-
list_del(&tmf_elem);
2247+
list_del(&arg->tmf_elem);
22362248

2237-
if (!rc)
2238-
fcport->active_tmf++;
2249+
if (!rc) {
2250+
ha->active_tmf++;
2251+
list_add_tail(&arg->tmf_elem, &ha->tmf_active);
2252+
}
22392253

22402254
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
22412255

@@ -2257,15 +2271,18 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
22572271
a.vha = fcport->vha;
22582272
a.fcport = fcport;
22592273
a.lun = lun;
2274+
a.flags = flags;
2275+
INIT_LIST_HEAD(&a.tmf_elem);
2276+
22602277
if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) {
22612278
a.modifier = MK_SYNC_ID_LUN;
2262-
2263-
if (qla_get_tmf(fcport))
2264-
return QLA_FUNCTION_FAILED;
22652279
} else {
22662280
a.modifier = MK_SYNC_ID;
22672281
}
22682282

2283+
if (qla_get_tmf(&a))
2284+
return QLA_FUNCTION_FAILED;
2285+
22692286
if (vha->hw->mqenable) {
22702287
for (i = 0; i < vha->hw->num_qpairs; i++) {
22712288
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,
22912308
goto bailout;
22922309

22932310
a.qpair = vha->hw->base_qpair;
2294-
a.flags = flags;
22952311
rval = __qla2x00_async_tm_cmd(&a);
22962312

22972313
bailout:
2298-
if (a.modifier == MK_SYNC_ID_LUN)
2299-
qla_put_tmf(fcport);
2300-
2314+
qla_put_tmf(&a);
23012315
return rval;
23022316
}
23032317

@@ -5526,7 +5540,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
55265540
INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
55275541
INIT_LIST_HEAD(&fcport->gnl_entry);
55285542
INIT_LIST_HEAD(&fcport->list);
5529-
INIT_LIST_HEAD(&fcport->tmf_pending);
55305543

55315544
INIT_LIST_HEAD(&fcport->sess_cmd_list);
55325545
spin_lock_init(&fcport->sess_cmd_lock);

drivers/scsi/qla2xxx/qla_os.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3009,6 +3009,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
30093009
atomic_set(&ha->num_pend_mbx_stage3, 0);
30103010
atomic_set(&ha->zio_threshold, DEFAULT_ZIO_THRESHOLD);
30113011
ha->last_zio_threshold = DEFAULT_ZIO_THRESHOLD;
3012+
INIT_LIST_HEAD(&ha->tmf_pending);
3013+
INIT_LIST_HEAD(&ha->tmf_active);
30123014

30133015
/* Assign ISP specific operations. */
30143016
if (IS_QLA2100(ha)) {

0 commit comments

Comments
 (0)