mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 07:37:31 -04:00
qcacmn: Optimize SRNG memory allocation
To avoid higher order allocations, allocate extra bytes for base address alignment only if unaligned address is returned. Change-Id: I185e58150952cd7e1ae0039e4382973465de5f68
This commit is contained in:
parent
b9780dd207
commit
1cd51ddb7c
1 changed files with 70 additions and 17 deletions
|
|
@ -1094,6 +1094,60 @@ static void dp_print_peer_table(struct dp_vdev *vdev)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* dp_srng_mem_alloc() - Allocate memory for SRNG
|
||||
* @soc : Data path soc handle
|
||||
* @srng : SRNG pointer
|
||||
* @align : Align size
|
||||
*
|
||||
* return: QDF_STATUS_SUCCESS on successful allocation
|
||||
* QDF_STATUS_E_NOMEM on failure
|
||||
*/
|
||||
static QDF_STATUS
|
||||
dp_srng_mem_alloc(struct dp_soc *soc, struct dp_srng *srng, uint32_t align)
|
||||
{
|
||||
srng->base_vaddr_unaligned =
|
||||
qdf_mem_alloc_consistent(soc->osdev,
|
||||
soc->osdev->dev,
|
||||
srng->alloc_size,
|
||||
&srng->base_paddr_unaligned);
|
||||
if (!srng->base_vaddr_unaligned) {
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
/* Re-allocate additional bytes to align base address only if
|
||||
* above allocation returns unaligned address. Reason for
|
||||
* trying exact size allocation above is, OS tries to allocate
|
||||
* blocks of size power-of-2 pages and then free extra pages.
|
||||
* e.g., of a ring size of 1MB, the allocation below will
|
||||
* request 1MB plus 7 bytes for alignment, which will cause a
|
||||
* 2MB block allocation,and that is failing sometimes due to
|
||||
* memory fragmentation.
|
||||
* dp_srng_mem_alloc should be replaced with
|
||||
* qdf_aligned_mem_alloc_consistent after fixing some known
|
||||
* shortcomings with this QDF function
|
||||
*/
|
||||
if ((unsigned long)(srng->base_paddr_unaligned) &
|
||||
(align - 1)) {
|
||||
qdf_mem_free_consistent(soc->osdev, soc->osdev->dev,
|
||||
srng->alloc_size,
|
||||
srng->base_vaddr_unaligned,
|
||||
srng->base_paddr_unaligned, 0);
|
||||
srng->alloc_size = srng->alloc_size + align - 1;
|
||||
srng->base_vaddr_unaligned =
|
||||
qdf_mem_alloc_consistent(soc->osdev,
|
||||
soc->osdev->dev,
|
||||
srng->alloc_size,
|
||||
&srng->base_paddr_unaligned);
|
||||
|
||||
if (!srng->base_vaddr_unaligned) {
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
}
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* dp_setup_srng - Internal function to setup SRNG rings used by data path
|
||||
*/
|
||||
|
|
@ -1114,29 +1168,28 @@ static int dp_srng_setup(struct dp_soc *soc, struct dp_srng *srng,
|
|||
|
||||
num_entries = (num_entries > max_entries) ? max_entries : num_entries;
|
||||
srng->hal_srng = NULL;
|
||||
srng->alloc_size = (num_entries * entry_size) + ring_base_align - 1;
|
||||
srng->alloc_size = num_entries * entry_size;
|
||||
srng->num_entries = num_entries;
|
||||
|
||||
if (!dp_is_soc_reinit(soc)) {
|
||||
srng->base_vaddr_unaligned =
|
||||
qdf_mem_alloc_consistent(soc->osdev,
|
||||
soc->osdev->dev,
|
||||
srng->alloc_size,
|
||||
&srng->base_paddr_unaligned);
|
||||
if (dp_srng_mem_alloc(soc, srng, ring_base_align) !=
|
||||
QDF_STATUS_SUCCESS) {
|
||||
dp_err("alloc failed - ring_type: %d, ring_num %d",
|
||||
ring_type, ring_num);
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
if (!srng->base_vaddr_unaligned) {
|
||||
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
|
||||
FL("alloc failed - ring_type: %d, ring_num %d"),
|
||||
ring_type, ring_num);
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
ring_params.ring_base_paddr =
|
||||
(qdf_dma_addr_t)qdf_align(
|
||||
(unsigned long)(srng->base_paddr_unaligned),
|
||||
ring_base_align);
|
||||
|
||||
ring_params.ring_base_vaddr =
|
||||
(void *)((unsigned long)(srng->base_vaddr_unaligned) +
|
||||
((unsigned long)(ring_params.ring_base_paddr) -
|
||||
(unsigned long)(srng->base_paddr_unaligned)));
|
||||
|
||||
ring_params.ring_base_vaddr = srng->base_vaddr_unaligned +
|
||||
((unsigned long)srng->base_vaddr_unaligned % ring_base_align);
|
||||
ring_params.ring_base_paddr = srng->base_paddr_unaligned +
|
||||
((unsigned long)(ring_params.ring_base_vaddr) -
|
||||
(unsigned long)srng->base_vaddr_unaligned);
|
||||
ring_params.num_entries = num_entries;
|
||||
|
||||
dp_verbose_debug("Ring type: %d, num:%d vaddr %pK paddr %pK entries %u",
|
||||
|
|
|
|||
Loading…
Reference in a new issue