mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 07:03:09 -04:00
msm: mhi_dev: Fix memory leak during channel reset/stop
mhi_ring_start() does not check whether we once ever allocated DMA buffer or not , causing it to leak memory if channel reset/stop happens. Also removing the free logic in mhi_deinit() as the check would suffice to prevent reallocation. Change-Id: I569560f9de9facc690131c56f657eadb77a12811 Signed-off-by: Subramanian Ananthanarayanan <skananth@codeaurora.org> Signed-off-by: Gauri Joshi <gaurjosh@codeaurora.org>
This commit is contained in:
parent
cc0c11d554
commit
296ddd7554
2 changed files with 43 additions and 59 deletions
|
|
@ -3688,36 +3688,6 @@ err:
|
|||
|
||||
static int mhi_deinit(struct mhi_dev *mhi)
|
||||
{
|
||||
int i = 0, ring_id = 0;
|
||||
struct mhi_dev_ring *ring;
|
||||
|
||||
ring_id = mhi->cfg.channels + mhi->cfg.event_rings + 1;
|
||||
|
||||
for (i = 0; i < ring_id; i++) {
|
||||
ring = &mhi->ring[i];
|
||||
if (ring->state == RING_STATE_UINT)
|
||||
continue;
|
||||
|
||||
dma_free_coherent(mhi->dev, ring->ring_size *
|
||||
sizeof(union mhi_dev_ring_element_type),
|
||||
ring->ring_cache,
|
||||
ring->ring_cache_dma_handle);
|
||||
|
||||
if (mhi->use_edma)
|
||||
dma_free_coherent(mhi->dev, sizeof(u32),
|
||||
ring->msi_buffer.buf,
|
||||
ring->msi_buffer.dma_addr);
|
||||
if (ring->type == RING_TYPE_ER) {
|
||||
dma_free_coherent(mhi->dev, ring->ring_size *
|
||||
sizeof(uint64_t),
|
||||
ring->evt_rp_cache,
|
||||
ring->evt_rp_cache_dma_handle);
|
||||
dma_free_coherent(mhi->dev,
|
||||
sizeof(uint32_t),
|
||||
ring->msi_buf,
|
||||
ring->msi_buf_dma_handle);
|
||||
}
|
||||
}
|
||||
|
||||
mhi_dev_sm_exit(mhi);
|
||||
|
||||
|
|
@ -3737,10 +3707,11 @@ static int mhi_init(struct mhi_dev *mhi)
|
|||
return rc;
|
||||
}
|
||||
|
||||
mhi->ring = devm_kzalloc(&pdev->dev,
|
||||
(sizeof(struct mhi_dev_ring) *
|
||||
(mhi->cfg.channels + mhi->cfg.event_rings + 1)),
|
||||
GFP_KERNEL);
|
||||
if (!mhi->ring)
|
||||
mhi->ring = devm_kzalloc(&pdev->dev,
|
||||
(sizeof(struct mhi_dev_ring) *
|
||||
(mhi->cfg.channels + mhi->cfg.event_rings + 1)),
|
||||
GFP_KERNEL);
|
||||
if (!mhi->ring)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -3763,8 +3734,10 @@ static int mhi_init(struct mhi_dev *mhi)
|
|||
|
||||
spin_lock_init(&mhi->lock);
|
||||
spin_lock_init(&mhi->msi_lock);
|
||||
mhi->mmio_backup = devm_kzalloc(&pdev->dev,
|
||||
MHI_DEV_MMIO_RANGE, GFP_KERNEL);
|
||||
|
||||
if (!mhi->mmio_backup)
|
||||
mhi->mmio_backup = devm_kzalloc(&pdev->dev, MHI_DEV_MMIO_RANGE, GFP_KERNEL);
|
||||
|
||||
if (!mhi->mmio_backup)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
|||
|
|
@ -443,33 +443,43 @@ int mhi_ring_start(struct mhi_dev_ring *ring, union mhi_dev_ring_ctx *ctx,
|
|||
wr_offset = mhi_dev_ring_addr2ofst(ring,
|
||||
ring->ring_ctx->generic.wp);
|
||||
|
||||
ring->ring_cache = dma_alloc_coherent(mhi->dev,
|
||||
ring->ring_size *
|
||||
sizeof(union mhi_dev_ring_element_type),
|
||||
&ring->ring_cache_dma_handle,
|
||||
GFP_KERNEL);
|
||||
if (!ring->ring_cache)
|
||||
return -ENOMEM;
|
||||
if (!ring->ring_cache) {
|
||||
ring->ring_cache = dma_alloc_coherent(mhi->dev,
|
||||
ring->ring_size *
|
||||
sizeof(union mhi_dev_ring_element_type),
|
||||
&ring->ring_cache_dma_handle,
|
||||
GFP_KERNEL);
|
||||
if (!ring->ring_cache) {
|
||||
mhi_log(MHI_MSG_ERROR,
|
||||
"Failed to allocate ring cache\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (ring->type == RING_TYPE_ER) {
|
||||
ring->evt_rp_cache = dma_alloc_coherent(mhi->dev,
|
||||
sizeof(uint64_t) * ring->ring_size,
|
||||
&ring->evt_rp_cache_dma_handle,
|
||||
GFP_KERNEL);
|
||||
if (!ring->evt_rp_cache) {
|
||||
mhi_log(MHI_MSG_ERROR,
|
||||
"Failed to allocate evt rp cache\n");
|
||||
rc = -ENOMEM;
|
||||
goto cleanup;
|
||||
ring->evt_rp_cache = dma_alloc_coherent(mhi->dev,
|
||||
sizeof(uint64_t) * ring->ring_size,
|
||||
&ring->evt_rp_cache_dma_handle,
|
||||
GFP_KERNEL);
|
||||
if (!ring->evt_rp_cache) {
|
||||
mhi_log(MHI_MSG_ERROR,
|
||||
"Failed to allocate evt rp cache\n");
|
||||
rc = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
ring->msi_buf = dma_alloc_coherent(mhi->dev,
|
||||
sizeof(uint32_t),
|
||||
&ring->msi_buf_dma_handle,
|
||||
GFP_KERNEL);
|
||||
if (!ring->msi_buf) {
|
||||
mhi_log(MHI_MSG_ERROR, "Failed to allocate msi buf\n");
|
||||
rc = -ENOMEM;
|
||||
goto cleanup;
|
||||
ring->msi_buf = dma_alloc_coherent(mhi->dev,
|
||||
sizeof(uint32_t),
|
||||
&ring->msi_buf_dma_handle,
|
||||
GFP_KERNEL);
|
||||
if (!ring->msi_buf) {
|
||||
mhi_log(MHI_MSG_ERROR,
|
||||
"Failed to allocate msi buf\n");
|
||||
rc = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -512,7 +522,6 @@ int mhi_ring_start(struct mhi_dev_ring *ring, union mhi_dev_ring_ctx *ctx,
|
|||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
||||
cleanup:
|
||||
|
|
@ -521,11 +530,13 @@ cleanup:
|
|||
sizeof(union mhi_dev_ring_element_type),
|
||||
ring->ring_cache,
|
||||
ring->ring_cache_dma_handle);
|
||||
ring->ring_cache = NULL;
|
||||
if (ring->evt_rp_cache) {
|
||||
dma_free_coherent(mhi->dev,
|
||||
sizeof(uint64_t) * ring->ring_size,
|
||||
ring->evt_rp_cache,
|
||||
ring->evt_rp_cache_dma_handle);
|
||||
ring->evt_rp_cache = NULL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue