qcacld-3.0: Support unaligned consistent memory prealloc

Support unaligned consistent memory prealloc

Change-Id: I5c4aea4991ab08519b821cb06c09e5abb9a90ef6
CRs-Fixed: 2758967
This commit is contained in:
Jinwei Chen 2020-08-09 22:24:33 -07:00 • committed by snandini
commit d4f5bd413d
3 changed files with 220 additions and 9 deletions

View file

@ -24,7 +24,8 @@
#include <cdp_txrx_misc.h>
#include <dp_tx_desc.h>
#include <dp_rx.h>
#include <ce_api.h>
#include <ce_internal.h>
QDF_STATUS dp_txrx_init(ol_txrx_soc_handle soc, uint8_t pdev_id,
struct dp_txrx_config *config)
@ -193,6 +194,23 @@ struct dp_multi_page_prealloc {
struct qdf_mem_multi_page_t pages;
};
/**
* struct dp_consistent_prealloc_unaligned - element representing DP pre-alloc
unaligned memory
* @ring_type: HAL ring type
* @size: size of pre-alloc memory
* @in_use: whether this element is in use (occupied)
* @va_unaligned: unaligned virtual address
* @pa_unaligned: unaligned physical address
*/
struct dp_consistent_prealloc_unaligned {
enum hal_ring_type ring_type;
uint32_t size;
bool in_use;
void *va_unaligned;
qdf_dma_addr_t pa_unaligned;
};
static struct dp_consistent_prealloc g_dp_consistent_allocs[] = {
/* 5 REO DST rings */
{REO_DST, (sizeof(struct reo_destination_ring)) * REO_DST_RING_SIZE, 0, NULL, NULL, 0, 0},
@ -270,7 +288,7 @@ static struct dp_multi_page_prealloc g_dp_multi_page_allocs[] = {
{DP_TX_TSO_NUM_SEG_TYPE, TX_TSO_NUM_SEG_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } },
{DP_TX_TSO_NUM_SEG_TYPE, TX_TSO_NUM_SEG_DESC_SIZE, DP_TX_DESC_POOL_SIZE, 0, CACHEABLE, { 0 } },
/* DP RX DESCs pools */
/* DP RX DESCs BUF pools */
{DP_RX_DESC_BUF_TYPE, sizeof(union dp_rx_desc_list_elem_t),
WLAN_CFG_RX_SW_DESC_WEIGHT_SIZE * WLAN_CFG_RXDMA_REFILL_RING_SIZE, 0, CACHEABLE, { 0 } },
@ -288,11 +306,40 @@ static struct dp_multi_page_prealloc g_dp_multi_page_allocs[] = {
};
static struct dp_consistent_prealloc_unaligned
g_dp_consistent_unaligned_allocs[] = {
/* CE-0 */
{CE_SRC, (sizeof(struct ce_srng_src_desc) * 16 + CE_DESC_RING_ALIGN),
false, NULL, 0},
/* CE-1 */
{CE_DST, (sizeof(struct ce_srng_dest_desc) * 512 + CE_DESC_RING_ALIGN),
false, NULL, 0},
{CE_DST_STATUS, (sizeof(struct ce_srng_dest_status_desc) * 512
+ CE_DESC_RING_ALIGN), false, NULL, 0},
/* CE-2 */
{CE_DST, (sizeof(struct ce_srng_dest_desc) * 32 + CE_DESC_RING_ALIGN),
false, NULL, 0},
{CE_DST_STATUS, (sizeof(struct ce_srng_dest_status_desc) * 32
+ CE_DESC_RING_ALIGN), false, NULL, 0},
/* CE-3 */
{CE_SRC, (sizeof(struct ce_srng_src_desc) * 32 + CE_DESC_RING_ALIGN),
false, NULL, 0},
/* CE-4 */
{CE_SRC, (sizeof(struct ce_srng_src_desc) * 256 + CE_DESC_RING_ALIGN),
false, NULL, 0},
/* CE-5 */
{CE_DST, (sizeof(struct ce_srng_dest_desc) * 512 + CE_DESC_RING_ALIGN),
false, NULL, 0},
{CE_DST_STATUS, (sizeof(struct ce_srng_dest_status_desc) * 512
+ CE_DESC_RING_ALIGN), false, NULL, 0},
};
void dp_prealloc_deinit(void)
{
int i;
struct dp_consistent_prealloc *p;
struct dp_multi_page_prealloc *mp;
struct dp_consistent_prealloc_unaligned *up;
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
if (!qdf_ctx) {
@ -307,8 +354,9 @@ void dp_prealloc_deinit(void)
dp_warn("i %d: consistent_mem in use while free", i);
if (p->va_aligned) {
dp_debug("i %d: va aligned %pK pa aligned %llx size %d",
i, p->va_aligned, p->pa_aligned, p->size);
dp_debug("i %d: va aligned %pK pa aligned %pK size %d",
i, p->va_aligned, (void *)p->pa_aligned,
p->size);
qdf_mem_free_consistent(qdf_ctx, qdf_ctx->dev,
p->size,
p->va_unaligned,
@ -334,6 +382,24 @@ void dp_prealloc_deinit(void)
qdf_mem_zero(mp, sizeof(*mp));
}
}
for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs); i++) {
up = &g_dp_consistent_unaligned_allocs[i];
if (qdf_unlikely(up->in_use))
dp_info("i %d: unaligned mem in use while free", i);
if (up->va_unaligned) {
dp_info("i %d: va unalign %pK pa unalign %pK size %d",
i, up->va_unaligned,
(void *)up->pa_unaligned, up->size);
qdf_mem_free_consistent(qdf_ctx, qdf_ctx->dev,
up->size,
up->va_unaligned,
up->pa_unaligned, 0);
qdf_mem_zero(up, sizeof(*up));
}
}
}
QDF_STATUS dp_prealloc_init(void)
@ -341,6 +407,7 @@ QDF_STATUS dp_prealloc_init(void)
int i;
struct dp_consistent_prealloc *p;
struct dp_multi_page_prealloc *mp;
struct dp_consistent_prealloc_unaligned *up;
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
if (!qdf_ctx) {
@ -359,14 +426,13 @@ QDF_STATUS dp_prealloc_init(void)
&p->pa_unaligned,
&p->pa_aligned,
DP_RING_BASE_ALIGN);
if (!p->va_unaligned) {
if (qdf_unlikely(!p->va_unaligned)) {
dp_warn("i %d: unable to preallocate %d bytes memory!",
i, p->size);
break;
}
dp_debug("i %d: va aligned %pK pa aligned %llx size %d", i,
p->va_aligned, p->pa_aligned, p->size);
dp_debug("i %d: va aligned %pK pa aligned %pK size %d",
i, p->va_aligned, (void *)p->pa_aligned, p->size);
}
if (i != QDF_ARRAY_SIZE(g_dp_consistent_allocs)) {
@ -399,6 +465,32 @@ QDF_STATUS dp_prealloc_init(void)
goto deinit;
}
for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs); i++) {
up = &g_dp_consistent_unaligned_allocs[i];
up->in_use = 0;
up->va_unaligned = qdf_mem_alloc_consistent(qdf_ctx,
qdf_ctx->dev,
up->size,
&up->pa_unaligned);
if (qdf_unlikely(!up->va_unaligned)) {
dp_warn("i %d: fail to prealloc unaligned %d bytes!",
i, up->size);
break;
}
dp_info("i %d: va unalign %pK pa unalign %pK size %d",
i, up->va_unaligned,
(void *)up->pa_unaligned, up->size);
}
if (i != QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs)) {
dp_info("unable to allocate unaligned memory!");
/*
* Only if unaligned memory prealloc fail, is deinit
* necessary for all other DP srng/multi-pages memory?
*/
goto deinit;
}
return QDF_STATUS_SUCCESS;
deinit:
dp_prealloc_deinit();
@ -516,11 +608,55 @@ void dp_prealloc_put_multi_pages(uint32_t desc_type,
}
}
if (!mp_found)
if (qdf_unlikely(!mp_found))
dp_warn("Not prealloc pages %pK desc_type %d cacheable_pages %pK dma_pages %pK",
pages,
desc_type,
pages->cacheable_pages,
pages->dma_pages);
}
void *dp_prealloc_get_consistent_mem_unaligned(size_t size,
qdf_dma_addr_t *base_addr,
uint32_t ring_type)
{
int i;
struct dp_consistent_prealloc_unaligned *up;
for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs); i++) {
up = &g_dp_consistent_unaligned_allocs[i];
if (ring_type == up->ring_type && size == up->size &&
up->va_unaligned && !up->in_use) {
up->in_use = true;
*base_addr = up->pa_unaligned;
dp_info("i %d: va unalign %pK pa unalign %pK size %d",
i, up->va_unaligned,
(void *)up->pa_unaligned, up->size);
return up->va_unaligned;
}
}
return NULL;
}
void dp_prealloc_put_consistent_mem_unaligned(void *va_unaligned)
{
int i;
struct dp_consistent_prealloc_unaligned *up;
for (i = 0; i < QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs); i++) {
up = &g_dp_consistent_unaligned_allocs[i];
if (va_unaligned == up->va_unaligned) {
dp_info("index %d, returned", i);
up->in_use = false;
qdf_mem_zero(up->va_unaligned, up->size);
break;
}
}
if (i == QDF_ARRAY_SIZE(g_dp_consistent_unaligned_allocs))
dp_err("unable to find vaddr %pK", va_unaligned);
}
#endif

View file

@ -527,6 +527,28 @@ void dp_prealloc_get_multi_pages(uint32_t src_type,
void dp_prealloc_put_multi_pages(uint32_t src_type,
struct qdf_mem_multi_page_t *pages);
/**
* dp_prealloc_get_consistent_mem_unaligned() - gets pre-alloc unaligned
consistent memory
* @size: total memory size
* @base_addr: pointer to dma address
* @ring_type: HAL ring type that requires memory
*
* Return: memory virtual address pointer, NULL if fail
*/
void *dp_prealloc_get_consistent_mem_unaligned(size_t size,
qdf_dma_addr_t *base_addr,
uint32_t ring_type);
/**
* dp_prealloc_put_consistent_mem_unaligned() - puts back pre-alloc unaligned
consistent memory
* @va_unaligned: memory virtual address pointer
*
* Return: None
*/
void dp_prealloc_put_consistent_mem_unaligned(void *va_unaligned);
#else
static inline QDF_STATUS dp_prealloc_init(void) { return QDF_STATUS_SUCCESS; }

View file

@ -95,6 +95,55 @@ static int hdd_get_bandwidth_level(void *data)
return ret;
}
#ifdef DP_MEM_PRE_ALLOC
/**
* hdd_get_consistent_mem_unaligned() - API to get consistent unaligned mem
* @size: Size of memory required
* @paddr: Pointer to paddr to be filled in by API
* @ring_type: Pointer to ring type for which consistent memory is needed
*
* Return: Virtual address of consistent memory on success, else null
*/
static
void *hdd_get_consistent_mem_unaligned(size_t size,
qdf_dma_addr_t *paddr,
uint32_t ring_type)
{
return dp_prealloc_get_consistent_mem_unaligned(size, paddr,
ring_type);
}
/**
* hdd_put_consistent_mem_unaligned() - API to put consistent unaligned mem
* @vaddr: Virtual address of memory
*
* Return: None
*/
static
void hdd_put_consistent_mem_unaligned(void *vaddr)
{
dp_prealloc_put_consistent_mem_unaligned(vaddr);
}
#else
static
void *hdd_get_consistent_mem_unaligned(size_t size,
qdf_dma_addr_t *paddr,
uint32_t ring_type)
{
hdd_err_rl("prealloc not support!");
return NULL;
}
static
void hdd_put_consistent_mem_unaligned(void *vaddr)
{
hdd_err_rl("prealloc not support!");
}
#endif
/**
* hdd_set_recovery_in_progress() - API to set recovery in progress
* @data: Context
@ -172,6 +221,10 @@ static void hdd_hif_init_driver_state_callbacks(void *data,
cbk->is_driver_unloading = hdd_is_driver_unloading;
cbk->is_target_ready = hdd_is_target_ready;
cbk->get_bandwidth_level = hdd_get_bandwidth_level;
cbk->prealloc_get_consistent_mem_unaligned =
hdd_get_consistent_mem_unaligned;
cbk->prealloc_put_consistent_mem_unaligned =
hdd_put_consistent_mem_unaligned;
}
#ifdef FORCE_WAKE