From bcc71cc3cde1468958a3ea859276d8d1a1a68265 Mon Sep 17 00:00:00 2001 From: Giridhar Malavali Date: Wed, 26 Sep 2018 22:05:17 -0700 Subject: [PATCH] scsi: qla2xxx: Fix for double free of SRB structure This patch fixes issue during switch command query where driver was freeing SRB resources multiple times Following stack trace will be seen [ 853.436234] BUG: unable to handle kernel NULL pointer dereference at 0000000000000001 [ 853.436348] IP: [] kmem_cache_alloc+0x74/0x1e0 [ 853.436476] PGD 0 [ 853.436601] Oops: 0000 [#1] SMP [ 853.454700] [] ? mod_timer+0x14a/0x220 [ 853.455543] [] mempool_alloc_slab+0x15/0x20 [ 853.456395] [] mempool_alloc+0x69/0x170 [ 853.457257] [] ? internal_add_timer+0x32/0x70 [ 853.458136] [] qla2xxx_queuecommand+0x29b/0x3f0 [qla2xxx] [ 853.459024] [] scsi_dispatch_cmd+0xaa/0x230 [ 853.459923] [] scsi_request_fn+0x4df/0x680 [ 853.460829] [] ? __switch_to+0xd7/0x510 [ 853.461747] [] __blk_run_queue+0x33/0x40 [ 853.462670] [] blk_delay_work+0x25/0x40 [ 853.463603] [] process_one_work+0x17a/0x440 [ 853.464546] [] worker_thread+0x126/0x3c0 [ 853.465501] [] ? manage_workers.isra.24+0x2a0/0x2a0 [ 853.466447] [] kthread+0xcf/0xe0 [ 853.467379] [] ? insert_kthread_work+0x40/0x40 [ 853.470172] Code: db e2 7e 49 8b 50 08 4d 8b 20 49 8b 40 10 4d 85 e4 0f 84 20 01 00 00 48 85 c0 0f 84 17 01 00 00 49 63 46 20 48 8d 4a 01 4d 8b 06 <49> 8b 1c 04 4c 89 e0 65 49 0f c7 08 0f 94 c0 84 c0 74 ba 49 63 [ 853.472072] RIP [] kmem_cache_alloc+0x74/0x1e0 [ 853.472971] RSP Fixes: 726b85487067 ("qla2xxx: Add framework for async fabric discovery") Cc: Signed-off-by: Giridhar Malavali Reviewed-by: Ewan D. Milne Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen --- drivers/scsi/qla2xxx/qla_gs.c | 3 +++ drivers/scsi/qla2xxx/qla_init.c | 15 +++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 4291e6324f8c..f4e8e9db7d2d 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -3027,6 +3027,9 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res) "Async done-%s res %x, WWPN %8phC \n", sp->name, res, fcport->port_name); + if (res == QLA_FUNCTION_TIMEOUT) + return; + if (res == (DID_ERROR << 16)) { /* entry status error */ goto done; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index ae28586c8ef2..c898deeae4af 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -52,12 +52,14 @@ qla2x00_sp_timeout(struct timer_list *t) struct srb_iocb *iocb; struct req_que *req; unsigned long flags; + struct qla_hw_data *ha = sp->vha->hw; - spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); + WARN_ON(irqs_disabled()); + spin_lock_irqsave(&ha->hardware_lock, flags); req = sp->qpair->req; req->outstanding_cmds[sp->handle] = NULL; iocb = &sp->u.iocb_cmd; - spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); + spin_unlock_irqrestore(&ha->hardware_lock, flags); iocb->timeout(sp); } @@ -970,6 +972,15 @@ void qla24xx_async_gpdb_sp_done(void *s, int res) fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); + if (res == QLA_FUNCTION_TIMEOUT) + return; + + if (res == QLA_FUNCTION_TIMEOUT) { + dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, + sp->u.iocb_cmd.u.mbx.in_dma); + return; + } + memset(&ea, 0, sizeof(ea)); ea.event = FCME_GPDB_DONE; ea.fcport = fcport; -- 2.45.2