Skip to content

Commit 8638559

Browse files
JordanYateskartben
authored andcommitted
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>
1 parent d879e84 commit 8638559

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

drivers/wifi/nrf_wifi/src/net_if.c

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ int nrf_wifi_if_send(const struct device *dev,
358358
struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
359359
struct rpu_host_stats *host_stats = NULL;
360360
void *nbuf = NULL;
361+
bool locked = false;
361362

362363
if (!dev || !pkt) {
363364
LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
@@ -371,24 +372,27 @@ int nrf_wifi_if_send(const struct device *dev,
371372
goto out;
372373
}
373374

375+
/* Allocate packet before locking mutex (blocks until allocation success) */
376+
nbuf = net_pkt_to_nbuf(pkt);
377+
374378
ret = k_mutex_lock(&vif_ctx_zep->vif_lock, K_FOREVER);
375379
if (ret != 0) {
376380
LOG_ERR("%s: Failed to lock vif_lock", __func__);
377-
goto out;
381+
goto drop;
378382
}
383+
locked = true;
379384

380385
rpu_ctx_zep = vif_ctx_zep->rpu_ctx_zep;
381386
if (!rpu_ctx_zep || !rpu_ctx_zep->rpu_ctx) {
382-
goto unlock;
387+
goto drop;
383388
}
384389

385390
sys_dev_ctx = wifi_dev_priv(rpu_ctx_zep->rpu_ctx);
386391
host_stats = &sys_dev_ctx->host_stats;
387-
nbuf = net_pkt_to_nbuf(pkt);
388-
if (!nbuf) {
389-
LOG_DBG("Failed to allocate net_pkt");
390-
host_stats->total_tx_drop_pkts++;
391-
goto out;
392+
393+
if (nbuf == NULL) {
394+
LOG_ERR("%s: allocation failed", __func__);
395+
goto drop;
392396
}
393397

394398
#ifdef CONFIG_NRF70_RAW_DATA_TX
@@ -415,10 +419,16 @@ int nrf_wifi_if_send(const struct device *dev,
415419
#endif /* CONFIG_NRF70_RAW_DATA_TX */
416420
goto unlock;
417421
drop:
418-
host_stats->total_tx_drop_pkts++;
419-
nrf_wifi_osal_nbuf_free(nbuf);
422+
if (host_stats != NULL) {
423+
host_stats->total_tx_drop_pkts++;
424+
}
425+
if (nbuf != NULL) {
426+
nrf_wifi_osal_nbuf_free(nbuf);
427+
}
420428
unlock:
421-
k_mutex_unlock(&vif_ctx_zep->vif_lock);
429+
if (locked) {
430+
k_mutex_unlock(&vif_ctx_zep->vif_lock);
431+
}
422432
#else
423433
ARG_UNUSED(dev);
424434
ARG_UNUSED(pkt);

0 commit comments

Comments
 (0)