wifi: nrf_wifi: net_if: allocate memory before mutex
Allocate the memory in `nrf_wifi_if_send` *before* taking the nrf70 global mutex. This prevents the function from deadlocking the application if attempting to send under memory-pressure, since many of the memory release paths also happen under the global mutex. Signed-off-by: Jordan Yates <jordan@embeint.com>
This commit is contained in:
parent
d879e8482f
commit
86385590c2
1 changed files with 20 additions and 10 deletions
|
@ -358,6 +358,7 @@ int nrf_wifi_if_send(const struct device *dev,
|
|||
struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
|
||||
struct rpu_host_stats *host_stats = NULL;
|
||||
void *nbuf = NULL;
|
||||
bool locked = false;
|
||||
|
||||
if (!dev || !pkt) {
|
||||
LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
|
||||
|
@ -371,24 +372,27 @@ int nrf_wifi_if_send(const struct device *dev,
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* Allocate packet before locking mutex (blocks until allocation success) */
|
||||
nbuf = net_pkt_to_nbuf(pkt);
|
||||
|
||||
ret = k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
|
||||
if (ret != 0) {
|
||||
LOG_ERR("%s: Failed to lock vif_lock", __func__);
|
||||
goto out;
|
||||
goto drop;
|
||||
}
|
||||
locked = true;
|
||||
|
||||
rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
|
||||
if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) {
|
||||
goto unlock;
|
||||
goto drop;
|
||||
}
|
||||
|
||||
sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx);
|
||||
host_stats = &sys_dev_ctx->host_stats;
|
||||
nbuf = net_pkt_to_nbuf(pkt);
|
||||
if (!nbuf) {
|
||||
LOG_DBG("Failed to allocate net_pkt");
|
||||
host_stats->total_tx_drop_pkts++;
|
||||
goto out;
|
||||
|
||||
if (nbuf == NULL) {
|
||||
LOG_ERR("%s: allocation failed", __func__);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NRF70_RAW_DATA_TX
|
||||
|
@ -415,10 +419,16 @@ int nrf_wifi_if_send(const struct device *dev,
|
|||
#endif /* CONFIG_NRF70_RAW_DATA_TX */
|
||||
goto unlock;
|
||||
drop:
|
||||
if (host_stats != NULL) {
|
||||
host_stats->total_tx_drop_pkts++;
|
||||
}
|
||||
if (nbuf != NULL) {
|
||||
nrf_wifi_osal_nbuf_free(nbuf);
|
||||
}
|
||||
unlock:
|
||||
if (locked) {
|
||||
k_mutex_unlock(&vif_ctx_zep->vif_lock);
|
||||
}
|
||||
#else
|
||||
ARG_UNUSED(dev);
|
||||
ARG_UNUSED(pkt);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue