Skip to content

Commit 35985b0

Browse files
Quinn Trangregkh
authored andcommitted
scsi: qla2xxx: Fix task management cmd fail due to unavailable resource
commit 6a87679 upstream. 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]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 843665c commit 35985b0

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
@@ -2535,6 +2535,7 @@ enum rscn_addr_format {
25352535
typedef struct fc_port {
25362536
struct list_head list;
25372537
struct scsi_qla_host *vha;
2538+
struct list_head tmf_pending;
25382539

25392540
unsigned int conf_compl_supported:1;
25402541
unsigned int deleted:2;
@@ -2555,6 +2556,8 @@ typedef struct fc_port {
25552556
unsigned int do_prli_nvme:1;
25562557

25572558
uint8_t nvme_flag;
2559+
uint8_t active_tmf;
2560+
#define MAX_ACTIVE_TMF 8
25582561

25592562
uint8_t node_name[WWN_SIZE];
25602563
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
@@ -2150,25 +2150,74 @@ __qla2x00_async_tm_cmd(struct tmf_arg *arg)
21502150
return rval;
21512151
}
21522152

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

2163-
init_completion(&comp);
21642210
a.vha = fcport->vha;
21652211
a.fcport = fcport;
21662212
a.lun = lun;
2167-
2168-
if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA))
2213+
if (flags & (TCF_LUN_RESET|TCF_ABORT_TASK_SET|TCF_CLEAR_TASK_SET|TCF_CLEAR_ACA)) {
21692214
a.modifier = MK_SYNC_ID_LUN;
2170-
else
2215+
2216+
if (qla_get_tmf(fcport))
2217+
return QLA_FUNCTION_FAILED;
2218+
} else {
21712219
a.modifier = MK_SYNC_ID;
2220+
}
21722221

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

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

@@ -5422,6 +5474,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
54225474
INIT_WORK(&fcport->reg_work, qla_register_fcport_fn);
54235475
INIT_LIST_HEAD(&fcport->gnl_entry);
54245476
INIT_LIST_HEAD(&fcport->list);
5477+
INIT_LIST_HEAD(&fcport->tmf_pending);
54255478

54265479
INIT_LIST_HEAD(&fcport->sess_cmd_list);
54275480
spin_lock_init(&fcport->sess_cmd_lock);

0 commit comments

Comments
 (0)