qcacmn: Cleanup WBUFF code to support additional modules

Currently, WBUFF logic is being used only for WMI TX buffers and the
logic is closely tied to the WMI TX buffers alone. It is cumbersome
to extend the support of WBUFF for additional modules in the current
state.

Cleanup the WBUFF code and make it generic to add future module
additions.

Change-Id: Ib20ddd487b4e88c3225da1883ad9ade722c2a606
CRs-Fixed: 3520811
このコミットが含まれているのは:
Manikanta Pubbisetty
2023-06-06 10:23:45 +05:30
committed by Rahul Choudhary
コミット 9b27c6e104
4個のファイルの変更130行の追加155行の削除

ファイルの表示

@@ -28,25 +28,22 @@
#include <qdf_status.h> #include <qdf_status.h>
#include <qdf_nbuf.h> #include <qdf_nbuf.h>
/* wbuff available pools */ enum wbuff_module_id {
/* Pool of nbuf size 256 bytes */ WBUFF_MODULE_WMI_TX,
#define WBUFF_POOL_0 0 WBUFF_MAX_MODULES,
/* Pool of nbuf size 512 bytes */ };
#define WBUFF_POOL_1 1
/* Pool of nbuf size 1024 bytes */
#define WBUFF_POOL_2 2
/* Pool of nbuf 2048 bytes */
#define WBUFF_POOL_3 3
/** /**
* struct wbuff_alloc_request - allocation structure for registering each * struct wbuff_alloc_request - allocation structure for registering each
* pool for wbuff module. * pool for wbuff module.
* @slot: pool_slot identifier * @pool_id: pool identifier
* @size: number of buffers for @pool_slot * @pool_size: number of buffers for @pool_id
* @buffer_size: size of each buffer in this @pool_id
*/ */
struct wbuff_alloc_request { struct wbuff_alloc_request {
uint8_t slot; uint8_t pool_id;
uint16_t size; uint16_t pool_size;
uint16_t buffer_size;
}; };
/* Opaque handle for wbuff */ /* Opaque handle for wbuff */
@@ -72,16 +69,17 @@ QDF_STATUS wbuff_module_deinit(void);
/** /**
* wbuff_module_register() - Registers a module with wbuff * wbuff_module_register() - Registers a module with wbuff
* @req: allocation request from registered module * @req: allocation request from registered module
* @num: number of pools required * @num_pools: number of pools required
* @reserve: nbuf headroom to start with * @reserve: nbuf headroom to start with
* @align: alignment for the nbuf * @align: alignment for the nbuf
* @module_id: module identifier
* *
* Return: Handle if registration success * Return: Handle if registration success
* NULL if registration failure * NULL if registration failure
*/ */
struct wbuff_mod_handle * struct wbuff_mod_handle *
wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num, wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num_pools,
int reserve, int align); int reserve, int align, enum wbuff_module_id module_id);
/** /**
* wbuff_module_deregister() - De-registers a module with wbuff * wbuff_module_deregister() - De-registers a module with wbuff
@@ -127,8 +125,8 @@ static inline QDF_STATUS wbuff_module_deinit(void)
} }
static inline struct wbuff_mod_handle * static inline struct wbuff_mod_handle *
wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num, wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num_pools,
int reserve, int align) int reserve, int align, enum wbuff_module_id module_id)
{ {
return NULL; return NULL;
} }

ファイルの表示

@@ -27,43 +27,15 @@
#include <qdf_nbuf.h> #include <qdf_nbuf.h>
/* Number of modules supported by wbuff */
#define WBUFF_MAX_MODULES 4
/* Number of pools supported per module */ /* Number of pools supported per module */
#define WBUFF_MAX_POOLS 4 #define WBUFF_MAX_POOLS 4
/* Max buffer size supported by wbuff in bytes */
#define WBUFF_MAX_BUFFER_SIZE 2048
/* wbuff pool buffer lengths in bytes*/
#define WBUFF_LEN_POOL0 256
#define WBUFF_LEN_POOL1 512
#define WBUFF_LEN_POOL2 1024
#define WBUFF_LEN_POOL3 2048
/* wbuff max pool sizes */
/* Allocation of size 256 bytes */
#define WBUFF_POOL_0_MAX 256
/* Allocation of size 512 bytes */
#define WBUFF_POOL_1_MAX 128
/* Allocation of size 1024 bytes */
#define WBUFF_POOL_2_MAX 64
/* Allocation of size 2048 bytes */
#define WBUFF_POOL_3_MAX 32
#define WBUFF_MODULE_ID_SHIFT 4 #define WBUFF_MODULE_ID_SHIFT 4
#define WBUFF_MODULE_ID_BITMASK 0xF0 #define WBUFF_MODULE_ID_BITMASK 0xF0
#define WBUFF_POOL_ID_SHIFT 1 #define WBUFF_POOL_ID_SHIFT 1
#define WBUFF_POOL_ID_BITMASK 0xE #define WBUFF_POOL_ID_BITMASK 0xE
/* Comparison array for maximum allocation per pool*/
uint16_t wbuff_alloc_max[WBUFF_MAX_POOLS] = {WBUFF_POOL_0_MAX,
WBUFF_POOL_1_MAX,
WBUFF_POOL_2_MAX,
WBUFF_POOL_3_MAX};
/** /**
* struct wbuff_handle - wbuff handle to the registered module * struct wbuff_handle - wbuff handle to the registered module
* @id: the identifier for the registered module. * @id: the identifier for the registered module.
@@ -72,6 +44,20 @@ struct wbuff_handle {
uint8_t id; uint8_t id;
}; };
/**
* struct wbuff_pool - structure representing wbuff pool
* @initialized: To identify whether pool is initialized
* @pool: nbuf pool
* @buffer_size: size of the buffer in this @pool
* @pool_id: pool identifier
*/
struct wbuff_pool {
bool initialized;
qdf_nbuf_t pool;
uint16_t buffer_size;
uint8_t pool_id;
};
/** /**
* struct wbuff_module - allocation holder for wbuff registered module * struct wbuff_module - allocation holder for wbuff registered module
* @registered: To identify whether module is registered * @registered: To identify whether module is registered
@@ -81,7 +67,7 @@ struct wbuff_handle {
* @handle: wbuff handle for the registered module * @handle: wbuff handle for the registered module
* @reserve: nbuf headroom to start with * @reserve: nbuf headroom to start with
* @align: alignment for the nbuf * @align: alignment for the nbuf
* @pool: pools for all available buffers for the module * @wbuff_pool: pools for all available buffers for the module
*/ */
struct wbuff_module { struct wbuff_module {
bool registered; bool registered;
@@ -90,7 +76,7 @@ struct wbuff_module {
struct wbuff_handle handle; struct wbuff_handle handle;
int reserve; int reserve;
int align; int align;
qdf_nbuf_t pool[WBUFF_MAX_POOLS]; struct wbuff_pool wbuff_pool[WBUFF_MAX_POOLS];
}; };
/** /**

ファイルの表示

@@ -32,72 +32,31 @@ struct wbuff_holder wbuff;
/** /**
* wbuff_get_pool_slot_from_len() - get pool_id from length * wbuff_get_pool_slot_from_len() - get pool_id from length
* @mod: wbuff module reference
* @len: length of the buffer * @len: length of the buffer
* *
* Return: pool_id * Return: pool_id
*/ */
static uint8_t wbuff_get_pool_slot_from_len(uint16_t len) static uint8_t
wbuff_get_pool_slot_from_len(struct wbuff_module *mod, uint16_t len)
{ {
if ((len > 0) && (len <= WBUFF_LEN_POOL0)) struct wbuff_pool *pool;
return WBUFF_POOL_0; uint16_t prev_buf_size = 0;
else if ((len > WBUFF_LEN_POOL0) && (len <= WBUFF_LEN_POOL1)) int i;
return WBUFF_POOL_1;
else if ((len > WBUFF_LEN_POOL1) && (len <= WBUFF_LEN_POOL2))
return WBUFF_POOL_2;
else
return WBUFF_POOL_3;
}
/** for (i = 0; i < WBUFF_MAX_POOLS; i++) {
* wbuff_get_len_from_pool_slot() - get len from pool_id pool = &mod->wbuff_pool[i];
* @pool_id: pool ID
*
* Return: nbuf length from pool_id
*/
static uint32_t wbuff_get_len_from_pool_slot(uint16_t pool_id)
{
uint32_t len = 0;
switch (pool_id) { if (!pool->initialized)
case 0: continue;
len = WBUFF_LEN_POOL0;
break;
case 1:
len = WBUFF_LEN_POOL1;
break;
case 2:
len = WBUFF_LEN_POOL2;
break;
case 3:
len = WBUFF_LEN_POOL3;
break;
default:
len = 0;
}
return len; if ((len > prev_buf_size) && (len <= pool->buffer_size))
}
/**
* wbuff_get_free_mod_slot() - get free module_id
*
* Return: module_id
*/
static uint8_t wbuff_get_free_mod_slot(void)
{
uint8_t module_id = 0;
for (module_id = 0; module_id < WBUFF_MAX_MODULES; module_id++) {
qdf_spin_lock_bh(&wbuff.mod[module_id].lock);
if (!wbuff.mod[module_id].registered) {
wbuff.mod[module_id].registered = true;
qdf_spin_unlock_bh(&wbuff.mod[module_id].lock);
break; break;
}
qdf_spin_unlock_bh(&wbuff.mod[module_id].lock); prev_buf_size = mod->wbuff_pool[i].buffer_size;
} }
return module_id; return i;
} }
/** /**
@@ -108,17 +67,13 @@ static uint8_t wbuff_get_free_mod_slot(void)
* Return: true if valid wbuff_alloc_request * Return: true if valid wbuff_alloc_request
* false if invalid wbuff_alloc_request * false if invalid wbuff_alloc_request
*/ */
static bool wbuff_is_valid_alloc_req(struct wbuff_alloc_request *req, static bool
uint8_t num) wbuff_is_valid_alloc_req(struct wbuff_alloc_request *req, uint8_t num)
{ {
uint16_t psize = 0; int i;
uint8_t alloc = 0, pool_id = 0;
for (alloc = 0; alloc < num; alloc++) { for (i = 0; i < num; i++) {
pool_id = req[alloc].slot; if (req[i].pool_id >= WBUFF_MAX_POOLS)
psize = req[alloc].size;
if ((pool_id > WBUFF_MAX_POOLS - 1) ||
(psize > wbuff_alloc_max[pool_id]))
return false; return false;
} }
@@ -142,8 +97,7 @@ static qdf_nbuf_t wbuff_prepare_nbuf(uint8_t module_id, uint8_t pool_id,
qdf_nbuf_t buf; qdf_nbuf_t buf;
unsigned long dev_scratch = 0; unsigned long dev_scratch = 0;
buf = qdf_nbuf_alloc(NULL, roundup(len + reserve, align), reserve, buf = qdf_nbuf_alloc(NULL, len, reserve, align, false);
align, false);
if (!buf) if (!buf)
return NULL; return NULL;
dev_scratch = module_id; dev_scratch = module_id;
@@ -184,7 +138,7 @@ QDF_STATUS wbuff_module_init(void)
mod = &wbuff.mod[module_id]; mod = &wbuff.mod[module_id];
qdf_spinlock_create(&mod->lock); qdf_spinlock_create(&mod->lock);
for (pool_id = 0; pool_id < WBUFF_MAX_POOLS; pool_id++) for (pool_id = 0; pool_id < WBUFF_MAX_POOLS; pool_id++)
mod->pool[pool_id] = NULL; mod->wbuff_pool[pool_id].pool = NULL;
mod->registered = false; mod->registered = false;
} }
wbuff.initialized = true; wbuff.initialized = true;
@@ -213,56 +167,69 @@ QDF_STATUS wbuff_module_deinit(void)
} }
struct wbuff_mod_handle * struct wbuff_mod_handle *
wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num, wbuff_module_register(struct wbuff_alloc_request *req, uint8_t num_pools,
int reserve, int align) int reserve, int align, enum wbuff_module_id module_id)
{ {
struct wbuff_module *mod = NULL; struct wbuff_module *mod = NULL;
struct wbuff_pool *wbuff_pool;
qdf_nbuf_t buf = NULL; qdf_nbuf_t buf = NULL;
uint32_t len = 0; uint32_t len;
uint16_t idx = 0, psize = 0; uint16_t pool_size;
uint8_t alloc = 0, module_id = 0, pool_id = 0; uint8_t pool_id;
int i;
int j;
if (!wbuff.initialized) if (!wbuff.initialized)
return NULL; return NULL;
if ((num == 0) || (num > WBUFF_MAX_POOLS)) if ((num_pools == 0) || (num_pools > WBUFF_MAX_POOLS))
return NULL; return NULL;
if (!wbuff_is_valid_alloc_req(req, num)) if (module_id >= WBUFF_MAX_MODULES)
return NULL; return NULL;
module_id = wbuff_get_free_mod_slot(); if (!wbuff_is_valid_alloc_req(req, num_pools))
if (module_id == WBUFF_MAX_MODULES)
return NULL; return NULL;
mod = &wbuff.mod[module_id]; mod = &wbuff.mod[module_id];
if (mod->registered)
return NULL;
mod->handle.id = module_id; mod->handle.id = module_id;
for (alloc = 0; alloc < num; alloc++) { for (i = 0; i < num_pools; i++) {
pool_id = req[alloc].slot; pool_id = req[i].pool_id;
psize = req[alloc].size; pool_size = req[i].pool_size;
len = wbuff_get_len_from_pool_slot(pool_id); len = req[i].buffer_size;
wbuff_pool = &mod->wbuff_pool[pool_id];
/** /**
* Allocate pool_cnt number of buffers for * Allocate pool_size number of buffers for
* the pool given by pool_id * the pool given by pool_id
*/ */
for (idx = 0; idx < psize; idx++) { for (j = 0; j < pool_size; j++) {
buf = wbuff_prepare_nbuf(module_id, pool_id, len, buf = wbuff_prepare_nbuf(module_id, pool_id, len,
reserve, align); reserve, align);
if (!buf) if (!buf)
continue; continue;
if (!mod->pool[pool_id]) {
if (!wbuff_pool->pool)
qdf_nbuf_set_next(buf, NULL); qdf_nbuf_set_next(buf, NULL);
mod->pool[pool_id] = buf; else
} else { qdf_nbuf_set_next(buf, wbuff_pool->pool);
qdf_nbuf_set_next(buf, mod->pool[pool_id]);
mod->pool[pool_id] = buf; wbuff_pool->pool = buf;
}
} }
wbuff_pool->pool_id = pool_id;
wbuff_pool->buffer_size = len;
wbuff_pool->initialized = true;
} }
mod->reserve = reserve; mod->reserve = reserve;
mod->align = align; mod->align = align;
mod->registered = true;
return (struct wbuff_mod_handle *)&mod->handle; return (struct wbuff_mod_handle *)&mod->handle;
} }
@@ -284,7 +251,7 @@ QDF_STATUS wbuff_module_deregister(struct wbuff_mod_handle *hdl)
qdf_spin_lock_bh(&mod->lock); qdf_spin_lock_bh(&mod->lock);
for (pool_id = 0; pool_id < WBUFF_MAX_POOLS; pool_id++) { for (pool_id = 0; pool_id < WBUFF_MAX_POOLS; pool_id++) {
first = mod->pool[pool_id]; first = mod->wbuff_pool[pool_id].pool;
while (first) { while (first) {
buf = first; buf = first;
first = qdf_nbuf_next(buf); first = qdf_nbuf_next(buf);
@@ -302,27 +269,33 @@ qdf_nbuf_t wbuff_buff_get(struct wbuff_mod_handle *hdl, uint32_t len,
{ {
struct wbuff_handle *handle; struct wbuff_handle *handle;
struct wbuff_module *mod = NULL; struct wbuff_module *mod = NULL;
struct wbuff_pool *wbuff_pool;
uint8_t module_id = 0; uint8_t module_id = 0;
uint8_t pool_id = 0; uint8_t pool_id = 0;
qdf_nbuf_t buf = NULL; qdf_nbuf_t buf = NULL;
handle = (struct wbuff_handle *)hdl; handle = (struct wbuff_handle *)hdl;
if ((!wbuff.initialized) || (!wbuff_is_valid_handle(handle)) || !len || if ((!wbuff.initialized) || (!wbuff_is_valid_handle(handle)) || !len)
(len > WBUFF_MAX_BUFFER_SIZE))
return NULL; return NULL;
module_id = handle->id; module_id = handle->id;
pool_id = wbuff_get_pool_slot_from_len(len);
mod = &wbuff.mod[module_id]; mod = &wbuff.mod[module_id];
pool_id = wbuff_get_pool_slot_from_len(mod, len);
if (pool_id == WBUFF_MAX_POOLS)
return NULL;
wbuff_pool = &mod->wbuff_pool[pool_id];
qdf_spin_lock_bh(&mod->lock); qdf_spin_lock_bh(&mod->lock);
if (mod->pool[pool_id]) { if (wbuff_pool->pool) {
buf = mod->pool[pool_id]; buf = wbuff_pool->pool;
mod->pool[pool_id] = qdf_nbuf_next(buf); wbuff_pool->pool = qdf_nbuf_next(buf);
mod->pending_returns++; mod->pending_returns++;
} }
qdf_spin_unlock_bh(&mod->lock); qdf_spin_unlock_bh(&mod->lock);
if (buf) { if (buf) {
qdf_nbuf_set_next(buf, NULL); qdf_nbuf_set_next(buf, NULL);
qdf_net_buf_debug_update_node(buf, func_name, line_num); qdf_net_buf_debug_update_node(buf, func_name, line_num);
@@ -336,6 +309,7 @@ qdf_nbuf_t wbuff_buff_put(qdf_nbuf_t buf)
qdf_nbuf_t buffer = buf; qdf_nbuf_t buffer = buf;
unsigned long pool_info = 0; unsigned long pool_info = 0;
uint8_t module_id = 0, pool_id = 0; uint8_t module_id = 0, pool_id = 0;
struct wbuff_pool *wbuff_pool;
if (!wbuff.initialized) if (!wbuff.initialized)
return buffer; return buffer;
@@ -351,13 +325,15 @@ qdf_nbuf_t wbuff_buff_put(qdf_nbuf_t buf)
if (module_id >= WBUFF_MAX_MODULES || pool_id >= WBUFF_MAX_POOLS) if (module_id >= WBUFF_MAX_MODULES || pool_id >= WBUFF_MAX_POOLS)
return NULL; return NULL;
wbuff_pool = &wbuff.mod[module_id].wbuff_pool[pool_id];
qdf_nbuf_reset(buffer, wbuff.mod[module_id].reserve, qdf_nbuf_reset(buffer, wbuff.mod[module_id].reserve,
wbuff.mod[module_id].align); wbuff.mod[module_id].align);
qdf_spin_lock_bh(&wbuff.mod[module_id].lock); qdf_spin_lock_bh(&wbuff.mod[module_id].lock);
if (wbuff.mod[module_id].registered) { if (wbuff.mod[module_id].registered) {
qdf_nbuf_set_next(buffer, wbuff.mod[module_id].pool[pool_id]); qdf_nbuf_set_next(buffer, wbuff_pool->pool);
wbuff.mod[module_id].pool[pool_id] = buffer; wbuff_pool->pool = buffer;
wbuff.mod[module_id].pending_returns--; wbuff.mod[module_id].pending_returns--;
buffer = NULL; buffer = NULL;
} }

ファイルの表示

@@ -112,6 +112,12 @@ typedef PREPACK struct {
/* Allocation of size 2048 bytes */ /* Allocation of size 2048 bytes */
#define WMI_WBUFF_POOL_3_SIZE 8 #define WMI_WBUFF_POOL_3_SIZE 8
/* wbuff pool buffer lengths in bytes for WMI*/
#define WMI_WBUFF_LEN_POOL0 256
#define WMI_WBUFF_LEN_POOL1 512
#define WMI_WBUFF_LEN_POOL2 1024
#define WMI_WBUFF_LEN_POOL3 2048
#define RX_DIAG_EVENT_WORK_PROCESS_MAX_COUNT 500 #define RX_DIAG_EVENT_WORK_PROCESS_MAX_COUNT 500
#ifdef WMI_INTERFACE_EVENT_LOGGING #ifdef WMI_INTERFACE_EVENT_LOGGING
@@ -3269,18 +3275,27 @@ qdf_export_symbol(wmi_unified_register_module);
static void wmi_wbuff_register(struct wmi_unified *wmi_handle) static void wmi_wbuff_register(struct wmi_unified *wmi_handle)
{ {
struct wbuff_alloc_request wbuff_alloc[4]; struct wbuff_alloc_request wbuff_alloc[4];
uint8_t reserve = WMI_MIN_HEAD_ROOM;
wbuff_alloc[0].slot = WBUFF_POOL_0; wbuff_alloc[0].pool_id = 0;
wbuff_alloc[0].size = WMI_WBUFF_POOL_0_SIZE; wbuff_alloc[0].pool_size = WMI_WBUFF_POOL_0_SIZE;
wbuff_alloc[1].slot = WBUFF_POOL_1; wbuff_alloc[0].buffer_size = roundup(WMI_WBUFF_LEN_POOL0 + reserve, 4);
wbuff_alloc[1].size = WMI_WBUFF_POOL_1_SIZE;
wbuff_alloc[2].slot = WBUFF_POOL_2;
wbuff_alloc[2].size = WMI_WBUFF_POOL_2_SIZE;
wbuff_alloc[3].slot = WBUFF_POOL_3;
wbuff_alloc[3].size = WMI_WBUFF_POOL_3_SIZE;
wmi_handle->wbuff_handle = wbuff_module_register(wbuff_alloc, 4, wbuff_alloc[1].pool_id = 1;
WMI_MIN_HEAD_ROOM, 4); wbuff_alloc[1].pool_size = WMI_WBUFF_POOL_1_SIZE;
wbuff_alloc[1].buffer_size = roundup(WMI_WBUFF_LEN_POOL1 + reserve, 4);
wbuff_alloc[2].pool_id = 2;
wbuff_alloc[2].pool_size = WMI_WBUFF_POOL_2_SIZE;
wbuff_alloc[2].buffer_size = roundup(WMI_WBUFF_LEN_POOL2 + reserve, 4);
wbuff_alloc[3].pool_id = 3;
wbuff_alloc[3].pool_size = WMI_WBUFF_POOL_3_SIZE;
wbuff_alloc[3].buffer_size = roundup(WMI_WBUFF_LEN_POOL3 + reserve, 4);
wmi_handle->wbuff_handle =
wbuff_module_register(wbuff_alloc, QDF_ARRAY_SIZE(wbuff_alloc),
reserve, 4, WBUFF_MODULE_WMI_TX);
} }
/** /**