Commit ebd3a52f authored by Quinn Tran's avatar Quinn Tran Committed by Ben Hutchings

qla2xxx: Fix crash due to null pointer access

commit fc1ffd6c upstream.

During code inspection, while investigating following stack trace
seen on one of the test setup, we found out there was possibility
of memory leak becuase driver was not unwinding the stack properly.

This issue has not been reproduced in a test environment or on a
customer setup.

Here's stack trace that was seen.

[1469877.797315] Call Trace:
[1469877.799940]  [<ffffffffa03ab6e9>] qla2x00_mem_alloc+0xb09/0x10c0 [qla2xxx]
[1469877.806980]  [<ffffffffa03ac50a>] qla2x00_probe_one+0x86a/0x1b50 [qla2xxx]
[1469877.814013]  [<ffffffff813b6d01>] ? __pm_runtime_resume+0x51/0xa0
[1469877.820265]  [<ffffffff8157c1f5>] ? _raw_spin_lock_irqsave+0x25/0x90
[1469877.826776]  [<ffffffff8157cd2d>] ? _raw_spin_unlock_irqrestore+0x6d/0x80
[1469877.833720]  [<ffffffff810741d1>] ? preempt_count_sub+0xb1/0x100
[1469877.839885]  [<ffffffff8157cd0c>] ? _raw_spin_unlock_irqrestore+0x4c/0x80
[1469877.846830]  [<ffffffff81319b9c>] local_pci_probe+0x4c/0xb0
[1469877.852562]  [<ffffffff810741d1>] ? preempt_count_sub+0xb1/0x100
[1469877.858727]  [<ffffffff81319c89>] pci_call_probe+0x89/0xb0
Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
[ bvanassche: Fixed spelling in patch description ]
Signed-off-by: default avatarBart Van Assche <bart.vanassche@sandisk.com>
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent fcc28a8b
...@@ -3393,7 +3393,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ...@@ -3393,7 +3393,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
sizeof(struct ct6_dsd), 0, sizeof(struct ct6_dsd), 0,
SLAB_HWCACHE_ALIGN, NULL); SLAB_HWCACHE_ALIGN, NULL);
if (!ctx_cachep) if (!ctx_cachep)
goto fail_free_gid_list; goto fail_free_srb_mempool;
} }
ha->ctx_mempool = mempool_create_slab_pool(SRB_MIN_REQ, ha->ctx_mempool = mempool_create_slab_pool(SRB_MIN_REQ,
ctx_cachep); ctx_cachep);
...@@ -3546,7 +3546,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ...@@ -3546,7 +3546,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
ha->loop_id_map = kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long), ha->loop_id_map = kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long),
GFP_KERNEL); GFP_KERNEL);
if (!ha->loop_id_map) if (!ha->loop_id_map)
goto fail_async_pd; goto fail_loop_id_map;
else { else {
qla2x00_set_reserved_loop_ids(ha); qla2x00_set_reserved_loop_ids(ha);
ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123, ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123,
...@@ -3555,6 +3555,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ...@@ -3555,6 +3555,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
return 0; return 0;
fail_loop_id_map:
dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma);
fail_async_pd: fail_async_pd:
dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
fail_ex_init_cb: fail_ex_init_cb:
...@@ -3582,6 +3584,10 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ...@@ -3582,6 +3584,10 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
ha->ms_iocb = NULL; ha->ms_iocb = NULL;
ha->ms_iocb_dma = 0; ha->ms_iocb_dma = 0;
if (ha->sns_cmd)
dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt),
ha->sns_cmd, ha->sns_cmd_dma);
fail_dma_pool: fail_dma_pool:
if (IS_QLA82XX(ha) || ql2xenabledif) { if (IS_QLA82XX(ha) || ql2xenabledif) {
dma_pool_destroy(ha->fcp_cmnd_dma_pool); dma_pool_destroy(ha->fcp_cmnd_dma_pool);
...@@ -3599,9 +3605,11 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, ...@@ -3599,9 +3605,11 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
kfree(ha->nvram); kfree(ha->nvram);
ha->nvram = NULL; ha->nvram = NULL;
fail_free_ctx_mempool: fail_free_ctx_mempool:
if (ha->ctx_mempool)
mempool_destroy(ha->ctx_mempool); mempool_destroy(ha->ctx_mempool);
ha->ctx_mempool = NULL; ha->ctx_mempool = NULL;
fail_free_srb_mempool: fail_free_srb_mempool:
if (ha->srb_mempool)
mempool_destroy(ha->srb_mempool); mempool_destroy(ha->srb_mempool);
ha->srb_mempool = NULL; ha->srb_mempool = NULL;
fail_free_gid_list: fail_free_gid_list:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment