Skip to content

Commit 6a87679

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix task management cmd fail due to unavailable resource
Task management command failed with status 2Ch which is a result of too many task management commands sent to the same target. Hence limit task management commands to 8 per target. Reported-by: kernel test robot <[email protected]> Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/ Cc: [email protected] Signed-off-by: Quinn Tran <[email protected]> Signed-off-by: Nilesh Javali <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Himanshu Madhani <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 9803fb5 commit 6a87679

File tree

2 files changed

+61
-5
lines changed

2 files changed

+61
-5
lines changed

drivers/scsi/qla2xxx/qla_def.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,6 +2542,7 @@ enum rscn_addr_format {
25422542
typedef struct fc_port {
25432543
struct list_head list;
25442544
struct scsi_qla_host *vha;
2545+
struct list_head tmf_pending;
25452546

25462547
unsigned int conf_compl_supported:1;
25472548
unsigned int deleted:2;
@@ -2562,6 +2563,8 @@ typedef struct fc_port {
25622563
unsigned int do_prli_nvme:1;
25632564

25642565
uint8_t nvme_flag;
2566+
uint8_t active_tmf;
2567+
#define MAX_ACTIVE_TMF 8
25652568

25662569
uint8_t node_name[WWN_SIZE];
25672570
uint8_t port_name[WWN_SIZE];

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2149,25 +2149,74 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
21492149
return rval;
21502150
}
21512151

2152+
static void qla_put_tmf(fc_port_t *fcport)
2153+
{
2154+
struct scsi_qla_host *vha = fcport->vha;
2155+
struct qla_hw_data *ha = vha->hw;
2156+
unsigned long flags;
2157+
2158+
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
2159+
fcport->active_tmf--;
2160+
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
2161+
}
2162+
2163+
static
2164+
int qla_get_tmf(fc_port_t *fcport)
2165+
{
2166+
struct scsi_qla_host *vha = fcport->vha;
2167+
struct qla_hw_data *ha = vha->hw;
2168+
unsigned long flags;
2169+
int rc = 0;
2170+
LIST_HEAD(tmf_elem);
2171+
2172+
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
2173+
list_add_tail(&tmf_elem, &fcport->tmf_pending);
2174+
2175+
while (fcport->active_tmf >= MAX_ACTIVE_TMF) {
2176+
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
2177+
2178+
msleep(1);
2179+
2180+
spin_lock_irqsave(&ha->tgt.sess_lock, flags);
2181+
if (fcport->deleted) {
2182+
rc = EIO;
2183+
break;
2184+
}
2185+
if (fcport->active_tmf < MAX_ACTIVE_TMF &&
2186+
list_is_first(&tmf_elem, &fcport->tmf_pending))
2187+
break;
2188+
}
2189+
2190+
list_del(&tmf_elem);
2191+
2192+
if (!rc)
2193+
fcport->active_tmf++;
2194+
2195+
spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
2196+
2197+
return rc;
2198+
}
2199+
21522200
int
21532201
qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
21542202
uint32_t tag)
21552203
{
21562204
struct scsi_qla_host *vha = fcport->vha;
21572205
struct qla_qpair *qpair;
21582206
struct tmf_arg a;
2159-
struct completion comp;
21602207
int i, rval;
21612208

2162-
init_completion(&comp);
21632209
a.vha = fcport->vha;
21642210
a.fcport = fcport;
21652211
a.lun = lun;
2166-
2167-
if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA))
2212+
if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) {
21682213
a.modifier = MK_SYNC_ID_LUN;
2169-
else
2214+
2215+
if (qla_get_tmf(fcport))
2216+
return QLA_FUNCTION_FAILED;
2217+
} else {
21702218
a.modifier = MK_SYNC_ID;
2219+
}
21712220

21722221
if (vha->hw->mqenable) {
21732222
for (i = 0; i < vha->hw->num_qpairs; i++) {
@@ -2186,6 +2235,9 @@ qla2x00_async_tm_cmd(fc_port_t *fcport, uint32_t flags, uint64_t lun,
21862235
a.flags = flags;
21872236
rval = __qla2x00_async_tm_cmd(&a);
21882237

2238+
if (a.modifier == MK_SYNC_ID_LUN)
2239+
qla_put_tmf(fcport);
2240+
21892241
return rval;
21902242
}
21912243

@@ -5400,6 +5452,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
54005452
INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
54015453
INIT_LIST_HEAD(&fcport->gnl_entry);
54025454
INIT_LIST_HEAD(&fcport->list);
5455+
INIT_LIST_HEAD(&fcport->tmf_pending);
54035456

54045457
INIT_LIST_HEAD(&fcport->sess_cmd_list);
54055458
spin_lock_init(&fcport->sess_cmd_lock);

0 commit comments

Comments
 (0)