Skip to content

Commit 80676d0

Browse files
Quinn Tranmartinkpetersen
authored andcommitted
scsi: qla2xxx: Fix session cleanup hang
On session cleanup, either an implicit LOGO or an implicit PRLO is used to flush IOs. If the flush command hit Queue Full condition, then it is dropped. This patch adds retry code to prevent command drop. Signed-off-by: Quinn Tran <quinn.tran@cavium.com> Signed-off-by: Himanshu Madhani <hmadhani@marvell.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
1 parent 4825034 commit 80676d0

File tree

2 files changed

+15
-7
lines changed

2 files changed

+15
-7
lines changed

drivers/scsi/qla2xxx/qla_iocb.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3645,23 +3645,22 @@ qla24xx_prlo_iocb(srb_t *sp, struct logio_entry_24xx *logio)
36453645
int
36463646
qla2x00_start_sp(srb_t *sp)
36473647
{
3648-
int rval;
3648+
int rval = QLA_SUCCESS;
36493649
scsi_qla_host_t *vha = sp->vha;
36503650
struct qla_hw_data *ha = vha->hw;
36513651
struct qla_qpair *qp = sp->qpair;
36523652
void *pkt;
36533653
unsigned long flags;
36543654

3655-
rval = QLA_FUNCTION_FAILED;
36563655
spin_lock_irqsave(qp->qp_lock_ptr, flags);
36573656
pkt = __qla2x00_alloc_iocbs(sp->qpair, sp);
36583657
if (!pkt) {
3658+
rval = EAGAIN;
36593659
ql_log(ql_log_warn, vha, 0x700c,
36603660
"qla2x00_alloc_iocbs failed.\n");
36613661
goto done;
36623662
}
36633663

3664-
rval = QLA_SUCCESS;
36653664
switch (sp->type) {
36663665
case SRB_LOGIN_CMD:
36673666
IS_FWI2_CAPABLE(ha) ?

drivers/scsi/qla2xxx/qla_os.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5204,14 +5204,14 @@ qla2x00_do_work(struct scsi_qla_host *vha)
52045204
struct qla_work_evt *e, *tmp;
52055205
unsigned long flags;
52065206
LIST_HEAD(work);
5207+
int rc;
52075208

52085209
spin_lock_irqsave(&vha->work_lock, flags);
52095210
list_splice_init(&vha->work_list, &work);
52105211
spin_unlock_irqrestore(&vha->work_lock, flags);
52115212

52125213
list_for_each_entry_safe(e, tmp, &work, list) {
5213-
list_del_init(&e->list);
5214-
5214+
rc = QLA_SUCCESS;
52155215
switch (e->type) {
52165216
case QLA_EVT_AEN:
52175217
fc_host_post_event(vha->host, fc_get_event_number(),
@@ -5225,7 +5225,7 @@ qla2x00_do_work(struct scsi_qla_host *vha)
52255225
e->u.logio.data);
52265226
break;
52275227
case QLA_EVT_ASYNC_LOGOUT:
5228-
qla2x00_async_logout(vha, e->u.logio.fcport);
5228+
rc = qla2x00_async_logout(vha, e->u.logio.fcport);
52295229
break;
52305230
case QLA_EVT_ASYNC_LOGOUT_DONE:
52315231
qla2x00_async_logout_done(vha, e->u.logio.fcport,
@@ -5270,7 +5270,7 @@ qla2x00_do_work(struct scsi_qla_host *vha)
52705270
qla24xx_do_nack_work(vha, e);
52715271
break;
52725272
case QLA_EVT_ASYNC_PRLO:
5273-
qla2x00_async_prlo(vha, e->u.logio.fcport);
5273+
rc = qla2x00_async_prlo(vha, e->u.logio.fcport);
52745274
break;
52755275
case QLA_EVT_ASYNC_PRLO_DONE:
52765276
qla2x00_async_prlo_done(vha, e->u.logio.fcport,
@@ -5303,6 +5303,15 @@ qla2x00_do_work(struct scsi_qla_host *vha)
53035303
e->u.fcport.fcport, false);
53045304
break;
53055305
}
5306+
5307+
if (rc == EAGAIN) {
5308+
/* put 'work' at head of 'vha->work_list' */
5309+
spin_lock_irqsave(&vha->work_lock, flags);
5310+
list_splice(&work, &vha->work_list);
5311+
spin_unlock_irqrestore(&vha->work_lock, flags);
5312+
break;
5313+
}
5314+
list_del_init(&e->list);
53065315
if (e->flags & QLA_EVT_FLAG_FREE)
53075316
kfree(e);
53085317

0 commit comments

Comments
 (0)