From aa0cb68c6fca79269c8033d1745d1c0d057f69da Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Mon, 29 Apr 2024 22:46:24 +0530 Subject: [PATCH] drivers: wifi: Create dedicated mem pool for Wi-Fi driver Create dedicated memory pools for Wi-Fi management and data operations (defaults: 20KB for management and 130KB for data). Setting Data pool to 110KB for non-Nordic SOCs to resolve RAM overflows seen in twister runs. Remove the `HEAP_MEM_POOL_ADD_SIZE_NRF70` hint since we are creating separate heaps for driver and not allocating from system heap. Signed-off-by: Ravi Dondaputi --- drivers/wifi/nrf_wifi/Kconfig.nrfwifi | 17 ++- drivers/wifi/nrf_wifi/src/fmac_main.c | 7 +- drivers/wifi/nrf_wifi/src/net_if.c | 4 +- drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c | 7 +- drivers/wifi/nrf_wifi/src/wpa_supp_if.c | 26 +++-- modules/nrf_wifi/bus/qspi_if.c | 5 +- modules/nrf_wifi/os/CMakeLists.txt | 1 + modules/nrf_wifi/os/shim.c | 129 +++++++++++++++++---- 8 files changed, 144 insertions(+), 52 deletions(-) diff --git a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi index 613709b5e6e..3912874f454 100644 --- a/drivers/wifi/nrf_wifi/Kconfig.nrfwifi +++ b/drivers/wifi/nrf_wifi/Kconfig.nrfwifi @@ -66,12 +66,6 @@ endchoice config NET_L2_ETHERNET default y if (!NRF70_RADIO_TEST && !NRF70_OFFLOADED_RAW_TX) -config HEAP_MEM_POOL_ADD_SIZE_NRF70 - # Use a maximum that works for typical use cases and boards, each sample/app can override - # this value if needed by using CONFIG_HEAP_MEM_POOL_IGNORE_MIN - def_int 25000 if NRF70_SCAN_ONLY - def_int 150000 - if NRF70_SYSTEM_MODE config NRF70_STA_MODE bool "nRF70 STA mode" @@ -529,8 +523,19 @@ config NRF70_RSSI_STALE_TIMEOUT_MS value as the driver does not store it and requires RPU to provide the information. +config NRF_WIFI_CTRL_HEAP_SIZE + int "Dedicated memory pool for control plane" + default 20000 + +config NRF_WIFI_DATA_HEAP_SIZE + int "Dedicated memory pool for data plane" + default 6000 if NRF70_SCAN_ONLY + default 110000 if !SOC_FAMILY_NORDIC_NRF + default 130000 + if NETWORKING # Finetune defaults for certain system components used by the driver + config SYSTEM_WORKQUEUE_STACK_SIZE default 4096 diff --git a/drivers/wifi/nrf_wifi/src/fmac_main.c b/drivers/wifi/nrf_wifi/src/fmac_main.c index fa3e6216975..bc151e91ae4 100644 --- a/drivers/wifi/nrf_wifi/src/fmac_main.c +++ b/drivers/wifi/nrf_wifi/src/fmac_main.c @@ -465,7 +465,8 @@ void reg_change_callbk_fn(void *vif_ctx, return; } - fmac_dev_ctx->reg_change = k_malloc(sizeof(struct nrf_wifi_event_regulatory_change)); + fmac_dev_ctx->reg_change = nrf_wifi_osal_mem_alloc(sizeof(struct + nrf_wifi_event_regulatory_change)); if (!fmac_dev_ctx->reg_change) { LOG_ERR("%s: Failed to allocate memory for reg_change", __func__); return; @@ -677,9 +678,9 @@ enum nrf_wifi_status nrf_wifi_fmac_dev_rem_zep(struct nrf_wifi_drv_priv_zep *drv nrf_wifi_fmac_dev_rem(rpu_ctx_zep->rpu_ctx); - k_free(rpu_ctx_zep->extended_capa); + nrf_wifi_osal_mem_free(rpu_ctx_zep->extended_capa); rpu_ctx_zep->extended_capa = NULL; - k_free(rpu_ctx_zep->extended_capa_mask); + nrf_wifi_osal_mem_free(rpu_ctx_zep->extended_capa_mask); rpu_ctx_zep->extended_capa_mask = NULL; rpu_ctx_zep->rpu_ctx = NULL; diff --git a/drivers/wifi/nrf_wifi/src/net_if.c b/drivers/wifi/nrf_wifi/src/net_if.c index 7433ee13535..5ecb9054f03 100644 --- a/drivers/wifi/nrf_wifi/src/net_if.c +++ b/drivers/wifi/nrf_wifi/src/net_if.c @@ -459,7 +459,7 @@ static void ip_maddr_event_handler(struct net_if *iface, goto unlock; } - mcast_info = k_calloc(sizeof(*mcast_info), sizeof(char)); + mcast_info = nrf_wifi_osal_mem_zalloc(sizeof(*mcast_info)); if (!mcast_info) { LOG_ERR("%s: Unable to allocate memory of size %d " @@ -501,7 +501,7 @@ static void ip_maddr_event_handler(struct net_if *iface, sizeof(mac_string_buf))); } unlock: - k_free(mcast_info); + nrf_wifi_osal_mem_free(mcast_info); k_mutex_unlock(&vif_ctx_zep->vif_lock); } #endif /* CONFIG_NRF70_STA_MODE */ diff --git a/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c b/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c index ceabdcf7f01..07560376987 100644 --- a/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c +++ b/drivers/wifi/nrf_wifi/src/wifi_mgmt_scan.c @@ -109,10 +109,9 @@ int nrf_wifi_disp_scan_zep(const struct device *dev, struct wifi_scan_params *pa vif_ctx_zep->disp_scan_cb = cb; - scan_info = k_calloc(sizeof(*scan_info) + + scan_info = nrf_wifi_osal_mem_zalloc(sizeof(*scan_info) + (num_scan_channels * - sizeof(scan_info->scan_params.center_frequency[0])), - sizeof(char)); + sizeof(scan_info->scan_params.center_frequency[0]))); if (!scan_info) { LOG_ERR("%s: Unable to allocate memory for scan_info (size: %d bytes)", @@ -226,7 +225,7 @@ int nrf_wifi_disp_scan_zep(const struct device *dev, struct wifi_scan_params *pa ret = 0; out: if (scan_info) { - k_free(scan_info); + nrf_wifi_osal_mem_free(scan_info); } k_mutex_unlock(&vif_ctx_zep->vif_lock); return ret; diff --git a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c index 4b28c7bb24e..6dc3315a64c 100644 --- a/drivers/wifi/nrf_wifi/src/wpa_supp_if.c +++ b/drivers/wifi/nrf_wifi/src/wpa_supp_if.c @@ -174,7 +174,7 @@ void nrf_wifi_wpa_supp_event_proc_scan_res(void *if_priv, beacon_ie_len = scan_res->beacon_ies_len; } - r = k_calloc(sizeof(*r) + ie_len + beacon_ie_len, sizeof(char)); + r = nrf_wifi_osal_mem_zalloc(sizeof(*r) + ie_len + beacon_ie_len); if (!r) { LOG_ERR("%s: Unable to allocate memory for scan result", __func__); @@ -254,7 +254,7 @@ void nrf_wifi_wpa_supp_event_proc_scan_res(void *if_priv, vif_ctx_zep->scan_in_progress = false; } - k_free(r); + nrf_wifi_osal_mem_free(r); } void nrf_wifi_wpa_supp_event_proc_auth_resp(void *if_priv, @@ -519,8 +519,8 @@ int nrf_wifi_wpa_supp_scan2(void *if_priv, struct wpa_driver_scan_params *params } } - scan_info = k_calloc(sizeof(*scan_info) + (num_freqs * sizeof(unsigned int)), - sizeof(char)); + scan_info = nrf_wifi_osal_mem_zalloc(sizeof(*scan_info) + + (num_freqs * sizeof(unsigned int))); if (!scan_info) { LOG_ERR("%s: Unable to allocate memory for scan info", __func__); @@ -579,7 +579,7 @@ int nrf_wifi_wpa_supp_scan2(void *if_priv, struct wpa_driver_scan_params *params ret = 0; out: if (scan_info) { - k_free(scan_info); + nrf_wifi_osal_mem_free(scan_info); } k_mutex_unlock(&vif_ctx_zep->vif_lock); return ret; @@ -1414,7 +1414,7 @@ int nrf_wifi_nl80211_send_mlme(void *if_priv, const u8 *data, k_mutex_lock(&mgmt_tx_lock, K_FOREVER); - mgmt_tx_info = k_calloc(sizeof(*mgmt_tx_info), sizeof(char)); + mgmt_tx_info = nrf_wifi_osal_mem_zalloc(sizeof(*mgmt_tx_info)); if (!mgmt_tx_info) { LOG_ERR("%s: Unable to allocate memory", __func__); @@ -1491,7 +1491,7 @@ int nrf_wifi_nl80211_send_mlme(void *if_priv, const u8 *data, out: if (mgmt_tx_info) { - k_free(mgmt_tx_info); + nrf_wifi_osal_mem_free(mgmt_tx_info); } k_mutex_unlock(&mgmt_tx_lock); k_mutex_unlock(&vif_ctx_zep->vif_lock); @@ -1610,22 +1610,24 @@ void nrf_wifi_wpa_supp_event_get_wiphy(void *if_priv, if ((wiphy_info->params_valid & NRF_WIFI_GET_WIPHY_VALID_EXTENDED_CAPABILITIES) && rpu_ctx_zep->extended_capa == NULL) { + /* To avoid overflowing the 100 column limit */ + unsigned char ec_len = wiphy_info->extended_capabilities_len; - rpu_ctx_zep->extended_capa = k_malloc(wiphy_info->extended_capabilities_len); + rpu_ctx_zep->extended_capa = nrf_wifi_osal_mem_alloc(ec_len); if (rpu_ctx_zep->extended_capa) { memcpy(rpu_ctx_zep->extended_capa, wiphy_info->extended_capabilities, - wiphy_info->extended_capabilities_len); + ec_len); } - rpu_ctx_zep->extended_capa_mask = k_malloc(wiphy_info->extended_capabilities_len); + rpu_ctx_zep->extended_capa_mask = nrf_wifi_osal_mem_alloc(ec_len); if (rpu_ctx_zep->extended_capa_mask) { memcpy(rpu_ctx_zep->extended_capa_mask, wiphy_info->extended_capabilities_mask, - wiphy_info->extended_capabilities_len); + ec_len); } else { - free(rpu_ctx_zep->extended_capa); + nrf_wifi_osal_mem_free(rpu_ctx_zep->extended_capa); rpu_ctx_zep->extended_capa = NULL; rpu_ctx_zep->extended_capa_len = 0; } diff --git a/modules/nrf_wifi/bus/qspi_if.c b/modules/nrf_wifi/bus/qspi_if.c index 8c381ff60c5..6107a5c4157 100644 --- a/modules/nrf_wifi/bus/qspi_if.c +++ b/modules/nrf_wifi/bus/qspi_if.c @@ -24,6 +24,7 @@ #include #include "spi_nor.h" +#include "osal_api.h" /* The QSPI bus node which the NRF70 is on */ #define QSPI_IF_BUS_NODE DT_NODELABEL(qspi) @@ -1287,7 +1288,7 @@ int qspi_hl_readw(unsigned int addr, void *data) len = len + (4 * qspi_cfg->qspi_slave_latency); - rxb = k_malloc(len); + rxb = nrf_wifi_osal_mem_alloc(len); if (rxb == NULL) { LOG_ERR("%s: ERROR ENOMEM line %d", __func__, __LINE__); @@ -1306,7 +1307,7 @@ int qspi_hl_readw(unsigned int addr, void *data) *(uint32_t *)data = *(uint32_t *)(rxb + (len - 4)); - k_free(rxb); + nrf_wifi_osal_mem_free(rxb); return status; } diff --git a/modules/nrf_wifi/os/CMakeLists.txt b/modules/nrf_wifi/os/CMakeLists.txt index 42610b9bf57..e4f9cf2a0b6 100644 --- a/modules/nrf_wifi/os/CMakeLists.txt +++ b/modules/nrf_wifi/os/CMakeLists.txt @@ -9,6 +9,7 @@ add_subdirectory(${ZEPHYR_NRF_WIFI_MODULE_DIR} nrf_wifi_osal) zephyr_library_named(nrf-wifi-shim) zephyr_include_directories(${CMAKE_CURRENT_LIST_DIR}) +zephyr_include_directories(${ZEPHYR_NRF_WIFI_MODULE_DIR}/os_if/inc) zephyr_library_sources( shim.c timer.c diff --git a/modules/nrf_wifi/os/shim.c b/modules/nrf_wifi/os/shim.c index ed6acf95846..5b7245edfbb 100644 --- a/modules/nrf_wifi/os/shim.c +++ b/modules/nrf_wifi/os/shim.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "shim.h" #include "work.h" @@ -27,6 +28,14 @@ #include "osal_ops.h" LOG_MODULE_REGISTER(wifi_nrf, CONFIG_WIFI_NRF70_LOG_LEVEL); +#if defined(CONFIG_NOCACHE_MEMORY) +K_HEAP_DEFINE_NOCACHE(wifi_drv_ctrl_mem_pool, CONFIG_NRF_WIFI_CTRL_HEAP_SIZE); +K_HEAP_DEFINE_NOCACHE(wifi_drv_data_mem_pool, CONFIG_NRF_WIFI_DATA_HEAP_SIZE); +#else +K_HEAP_DEFINE(wifi_drv_ctrl_mem_pool, CONFIG_NRF_WIFI_CTRL_HEAP_SIZE); +K_HEAP_DEFINE(wifi_drv_data_mem_pool, CONFIG_NRF_WIFI_DATA_HEAP_SIZE); +#endif /* CONFIG_NOCACHE_MEMORY */ +#define WORD_SIZE 4 struct zep_shim_intr_priv *intr_priv; @@ -34,14 +43,66 @@ static void *zep_shim_mem_alloc(size_t size) { size_t size_aligned = ROUND_UP(size, 4); - return k_malloc(size_aligned); + return k_heap_aligned_alloc(&wifi_drv_ctrl_mem_pool, WORD_SIZE, size_aligned, K_FOREVER); +} + +static void *zep_shim_data_mem_alloc(size_t size) +{ + size_t size_aligned = ROUND_UP(size, 4); + + return k_heap_aligned_alloc(&wifi_drv_data_mem_pool, WORD_SIZE, size_aligned, K_FOREVER); } static void *zep_shim_mem_zalloc(size_t size) { + void *ret; + size_t bounds; + size_t size_aligned = ROUND_UP(size, 4); - return k_calloc(size_aligned, sizeof(char)); + if (size_mul_overflow(size_aligned, sizeof(char), &bounds)) { + return NULL; + } + + ret = zep_shim_mem_alloc(bounds); + if (ret != NULL) { + (void)memset(ret, 0, bounds); + } + + return ret; +} + +static void *zep_shim_data_mem_zalloc(size_t size) +{ + void *ret; + size_t bounds; + + size_t size_aligned = ROUND_UP(size, 4); + + if (size_mul_overflow(size_aligned, sizeof(char), &bounds)) { + return NULL; + } + + ret = zep_shim_data_mem_alloc(bounds); + if (ret != NULL) { + (void)memset(ret, 0, bounds); + } + + return ret; +} + +static void zep_shim_mem_free(void *buf) +{ + if (buf) { + k_heap_free(&wifi_drv_ctrl_mem_pool, buf); + } +} + +static void zep_shim_data_mem_free(void *buf) +{ + if (buf) { + k_heap_free(&wifi_drv_data_mem_pool, buf); + } } static void *zep_shim_mem_cpy(void *dest, const void *src, size_t count) @@ -118,7 +179,7 @@ static void *zep_shim_spinlock_alloc(void) { struct k_mutex *lock = NULL; - lock = k_malloc(sizeof(*lock)); + lock = zep_shim_mem_zalloc(sizeof(*lock)); if (!lock) { LOG_ERR("%s: Unable to allocate memory for spinlock", __func__); @@ -129,7 +190,7 @@ static void *zep_shim_spinlock_alloc(void) static void zep_shim_spinlock_free(void *lock) { - k_free(lock); + k_heap_free(&wifi_drv_ctrl_mem_pool, lock); } static void zep_shim_spinlock_init(void *lock) @@ -213,16 +274,16 @@ static void *zep_shim_nbuf_alloc(unsigned int size) { struct nwb *nbuff; - nbuff = (struct nwb *)k_calloc(sizeof(struct nwb), sizeof(char)); + nbuff = (struct nwb *)zep_shim_data_mem_zalloc(sizeof(struct nwb)); if (!nbuff) { return NULL; } - nbuff->priv = k_calloc(size, sizeof(char)); + nbuff->priv = zep_shim_data_mem_zalloc(size); if (!nbuff->priv) { - k_free(nbuff); + zep_shim_data_mem_free(nbuff); return NULL; } @@ -241,8 +302,8 @@ static void zep_shim_nbuf_free(void *nbuf) return; } - k_free(((struct nwb *)nbuf)->priv); - k_free(nbuf); + zep_shim_data_mem_free(((struct nwb *)nbuf)->priv); + zep_shim_data_mem_free(nbuf); } static void zep_shim_nbuf_headroom_res(void *nbuf, unsigned int size) @@ -406,7 +467,7 @@ void *net_raw_pkt_from_nbuf(void *iface, void *frm, nwb_data = zep_shim_nbuf_data_get(nwb); total_len = raw_hdr_len + nwb_len; - data = (unsigned char *)k_malloc(total_len); + data = (unsigned char *)zep_shim_data_mem_zalloc(total_len); if (!data) { LOG_ERR("%s: Unable to allocate memory for sniffer data packet", __func__); goto out; @@ -428,7 +489,7 @@ void *net_raw_pkt_from_nbuf(void *iface, void *frm, } out: if (data != NULL) { - k_free(data); + zep_shim_data_mem_free(data); } if (pkt_free) { @@ -443,7 +504,7 @@ static void *zep_shim_llist_node_alloc(void) { struct zep_shim_llist_node *llist_node = NULL; - llist_node = k_calloc(sizeof(*llist_node), sizeof(char)); + llist_node = zep_shim_data_mem_zalloc(sizeof(*llist_node)); if (!llist_node) { LOG_ERR("%s: Unable to allocate memory for linked list node", __func__); @@ -457,7 +518,7 @@ static void *zep_shim_llist_node_alloc(void) static void zep_shim_llist_node_free(void *llist_node) { - k_free(llist_node); + zep_shim_data_mem_free(llist_node); } static void *zep_shim_llist_node_data_get(void *llist_node) @@ -482,7 +543,20 @@ static void *zep_shim_llist_alloc(void) { struct zep_shim_llist *llist = NULL; - llist = k_calloc(sizeof(*llist), sizeof(char)); + llist = zep_shim_data_mem_zalloc(sizeof(*llist)); + + if (!llist) { + LOG_ERR("%s: Unable to allocate memory for linked list", __func__); + } + + return llist; +} + +static void *zep_shim_ctrl_llist_alloc(void) +{ + struct zep_shim_llist *llist = NULL; + + llist = zep_shim_mem_zalloc(sizeof(*llist)); if (!llist) { LOG_ERR("%s: Unable to allocate memory for linked list", __func__); @@ -493,7 +567,12 @@ static void *zep_shim_llist_alloc(void) static void zep_shim_llist_free(void *llist) { - k_free(llist); + zep_shim_data_mem_free(llist); +} + +static void zep_shim_ctrl_llist_free(void *llist) +{ + zep_shim_mem_free(llist); } static void zep_shim_llist_init(void *llist) @@ -698,7 +777,7 @@ static void *zep_shim_bus_qspi_init(void) { struct zep_shim_bus_qspi_priv *qspi_priv = NULL; - qspi_priv = k_calloc(sizeof(*qspi_priv), sizeof(char)); + qspi_priv = zep_shim_mem_zalloc(sizeof(*qspi_priv)); if (!qspi_priv) { LOG_ERR("%s: Unable to allocate memory for qspi_priv", __func__); @@ -714,7 +793,7 @@ static void zep_shim_bus_qspi_deinit(void *os_qspi_priv) qspi_priv = os_qspi_priv; - k_free(qspi_priv); + zep_shim_mem_free(qspi_priv); } #ifdef CONFIG_NRF_WIFI_LOW_POWER @@ -789,7 +868,7 @@ static enum nrf_wifi_status zep_shim_bus_qspi_intr_reg(void *os_dev_ctx, void *c ARG_UNUSED(os_dev_ctx); - intr_priv = k_calloc(sizeof(*intr_priv), sizeof(char)); + intr_priv = zep_shim_mem_zalloc(sizeof(*intr_priv)); if (!intr_priv) { LOG_ERR("%s: Unable to allocate memory for intr_priv", __func__); @@ -805,7 +884,7 @@ static enum nrf_wifi_status zep_shim_bus_qspi_intr_reg(void *os_dev_ctx, void *c if (ret) { LOG_ERR("%s: request_irq failed", __func__); - k_free(intr_priv); + zep_shim_mem_free(intr_priv); intr_priv = NULL; goto out; } @@ -831,7 +910,7 @@ static void zep_shim_bus_qspi_intr_unreg(void *os_qspi_dev_ctx) k_work_cancel_delayable_sync(&intr_priv->work, &sync); - k_free(intr_priv); + zep_shim_mem_free(intr_priv); intr_priv = NULL; } @@ -840,7 +919,7 @@ static void *zep_shim_timer_alloc(void) { struct timer_list *timer = NULL; - timer = k_malloc(sizeof(*timer)); + timer = zep_shim_mem_zalloc(sizeof(*timer)); if (!timer) { LOG_ERR("%s: Unable to allocate memory for work", __func__); @@ -859,7 +938,7 @@ static void zep_shim_timer_init(void *timer, void (*callback)(unsigned long), un static void zep_shim_timer_free(void *timer) { - k_free(timer); + zep_shim_mem_free(timer); } static void zep_shim_timer_schedule(void *timer, unsigned long duration) @@ -907,7 +986,9 @@ static unsigned int zep_shim_strlen(const void *str) const struct nrf_wifi_osal_ops nrf_wifi_os_zep_ops = { .mem_alloc = zep_shim_mem_alloc, .mem_zalloc = zep_shim_mem_zalloc, - .mem_free = k_free, + .data_mem_zalloc = zep_shim_data_mem_zalloc, + .mem_free = zep_shim_mem_free, + .data_mem_free = zep_shim_data_mem_free, .mem_cpy = zep_shim_mem_cpy, .mem_set = zep_shim_mem_set, .mem_cmp = zep_shim_mem_cmp, @@ -936,7 +1017,9 @@ const struct nrf_wifi_osal_ops nrf_wifi_os_zep_ops = { .llist_node_data_set = zep_shim_llist_node_data_set, .llist_alloc = zep_shim_llist_alloc, + .ctrl_llist_alloc = zep_shim_ctrl_llist_alloc, .llist_free = zep_shim_llist_free, + .ctrl_llist_free = zep_shim_ctrl_llist_free, .llist_init = zep_shim_llist_init, .llist_add_node_tail = zep_shim_llist_add_node_tail, .llist_add_node_head = zep_shim_llist_add_node_head,