qcacmn: Fix a memory leak in qdf_mem_shared_mem_alloc

qdf_mem_shared_mem_alloc invokes qdf_mem_dma_get_sgtable which will alloc
memory.
This memory should be free in qdf_mem_shared_mem_free by sg_free_table.

Change-Id: I3ad4bd2ff7a80d4051f15dcb04e0265707c2712d
CRs-Fixed: 2131270
This commit is contained in:
Jiachao Wu
2017-10-23 14:41:19 +08:00
committed by nshrivas
parent b5ec642075
commit ae6c777bd1
3 changed files with 79 additions and 44 deletions

View File

@@ -568,11 +568,23 @@ qdf_mem_dma_get_sgtable(struct device *dev, void *sgt, void *cpu_addr,
return __qdf_os_mem_dma_get_sgtable(dev, sgt, cpu_addr, dma_addr, size); return __qdf_os_mem_dma_get_sgtable(dev, sgt, cpu_addr, dma_addr, size);
} }
/**
* qdf_mem_free_sgtable() - Free a previously allocated sg table
* @sgt: the mapped sg table header
*
* Return: None
*/
static inline void
qdf_mem_free_sgtable(struct sg_table *sgt)
{
__qdf_os_mem_free_sgtable(sgt);
}
/** /**
* qdf_dma_get_sgtable_dma_addr() - Assigns DMA address to scatterlist elements * qdf_dma_get_sgtable_dma_addr() - Assigns DMA address to scatterlist elements
* @sgt: scatter gather table pointer * @sgt: scatter gather table pointer
* *
* @Return: None * Return: None
*/ */
static inline void static inline void
qdf_dma_get_sgtable_dma_addr(struct sg_table *sgt) qdf_dma_get_sgtable_dma_addr(struct sg_table *sgt)
@@ -683,49 +695,9 @@ qdf_mem_set_dma_pa(qdf_device_t osdev,
* Allocate DMA memory which will be shared with external kernel module. This * Allocate DMA memory which will be shared with external kernel module. This
* information is needed for SMMU mapping. * information is needed for SMMU mapping.
* *
* Return: 0 suceess * Return: 0 success
*/ */
static inline qdf_shared_mem_t *qdf_mem_shared_mem_alloc(qdf_device_t osdev, qdf_shared_mem_t *qdf_mem_shared_mem_alloc(qdf_device_t osdev, uint32_t size);
uint32_t size)
{
qdf_shared_mem_t *shared_mem;
shared_mem = qdf_mem_malloc(sizeof(*shared_mem));
if (!shared_mem) {
__qdf_print("%s: Unable to allocate memory for shared resource struct\n",
__func__);
return NULL;
}
shared_mem->vaddr = qdf_mem_alloc_consistent(osdev, osdev->dev,
size, qdf_mem_get_dma_addr_ptr(osdev,
&shared_mem->mem_info));
if (!shared_mem->vaddr) {
__qdf_print("%s; Unable to allocate DMA memory for shared resource\n",
__func__);
qdf_mem_free(shared_mem);
return NULL;
}
qdf_mem_set_dma_size(osdev, &shared_mem->mem_info, size);
qdf_mem_zero(shared_mem->vaddr,
qdf_mem_get_dma_size(osdev, &shared_mem->mem_info));
qdf_mem_set_dma_pa(osdev, &shared_mem->mem_info,
qdf_mem_paddr_from_dmaaddr(osdev,
qdf_mem_get_dma_addr(osdev,
&shared_mem->mem_info)));
qdf_mem_dma_get_sgtable(osdev->dev,
(void *)&shared_mem->sgtable,
shared_mem->vaddr,
qdf_mem_get_dma_addr(osdev,
&shared_mem->mem_info),
qdf_mem_get_dma_size(osdev,
&shared_mem->mem_info));
qdf_dma_get_sgtable_dma_addr(&shared_mem->sgtable);
return shared_mem;
}
/** /**
* qdf_mem_shared_mem_free() - Free shared memory * qdf_mem_shared_mem_free() - Free shared memory
@@ -755,6 +727,7 @@ static inline void qdf_mem_shared_mem_free(qdf_device_t osdev,
qdf_get_dma_mem_context(shared_mem, qdf_get_dma_mem_context(shared_mem,
memctx)); memctx));
} }
qdf_mem_free_sgtable(&shared_mem->sgtable);
qdf_mem_free(shared_mem); qdf_mem_free(shared_mem);
} }

View File

@@ -266,11 +266,23 @@ __qdf_os_mem_dma_get_sgtable(struct device *dev, void *sgt, void *cpu_addr,
size); size);
} }
/**
* __qdf_os_mem_free_sgtable() - Free a previously allocated sg table
* @sgt: the mapped sg table header
*
* Return: None
*/
static inline void
__qdf_os_mem_free_sgtable(struct sg_table *sgt)
{
sg_free_table(sgt);
}
/** /**
* __qdf_dma_get_sgtable_dma_addr()-Assigns DMA address to scatterlist elements * __qdf_dma_get_sgtable_dma_addr()-Assigns DMA address to scatterlist elements
* @sgt: scatter gather table pointer * @sgt: scatter gather table pointer
* *
* @Return: None * Return: None
*/ */
static inline void static inline void
__qdf_dma_get_sgtable_dma_addr(struct sg_table *sgt) __qdf_dma_get_sgtable_dma_addr(struct sg_table *sgt)

View File

@@ -1468,6 +1468,56 @@ void qdf_mem_copy(void *dst_addr, const void *src_addr, uint32_t num_bytes)
} }
qdf_export_symbol(qdf_mem_copy); qdf_export_symbol(qdf_mem_copy);
qdf_shared_mem_t *qdf_mem_shared_mem_alloc(qdf_device_t osdev, uint32_t size)
{
qdf_shared_mem_t *shared_mem;
qdf_dma_addr_t dma_addr, paddr;
int ret;
shared_mem = qdf_mem_malloc(sizeof(*shared_mem));
if (!shared_mem) {
qdf_err("Unable to allocate memory for shared resource struct");
return NULL;
}
shared_mem->vaddr = qdf_mem_alloc_consistent(osdev, osdev->dev,
size, qdf_mem_get_dma_addr_ptr(osdev,
&shared_mem->mem_info));
if (!shared_mem->vaddr) {
qdf_err("Unable to allocate DMA memory for shared resource");
qdf_mem_free(shared_mem);
return NULL;
}
qdf_mem_set_dma_size(osdev, &shared_mem->mem_info, size);
size = qdf_mem_get_dma_size(osdev, &shared_mem->mem_info);
qdf_mem_zero(shared_mem->vaddr, size);
dma_addr = qdf_mem_get_dma_addr(osdev, &shared_mem->mem_info);
paddr = qdf_mem_paddr_from_dmaaddr(osdev, dma_addr);
qdf_mem_set_dma_pa(osdev, &shared_mem->mem_info, paddr);
ret = qdf_mem_dma_get_sgtable(osdev->dev, &shared_mem->sgtable,
shared_mem->vaddr, dma_addr, size);
if (ret) {
qdf_err("Unable to get DMA sgtable");
qdf_mem_free_consistent(osdev, osdev->dev,
shared_mem->mem_info.size,
shared_mem->vaddr,
dma_addr,
qdf_get_dma_mem_context(shared_mem,
memctx));
qdf_mem_free(shared_mem);
return NULL;
}
qdf_dma_get_sgtable_dma_addr(&shared_mem->sgtable);
return shared_mem;
}
qdf_export_symbol(qdf_mem_shared_mem_alloc);
/** /**
* qdf_mem_zero() - zero out memory * qdf_mem_zero() - zero out memory
* @ptr: pointer to memory that will be set to zero * @ptr: pointer to memory that will be set to zero