Skip to content

Commit 9071704

Browse files
krish2718fabiobaltieri
authored andcommitted
drivers: nrf_wifi: Fix deadlock in display scan and recovery
When running Zperf traffic + scan in the background eventual we hit a deadlock: * sysworkq: recovery->stop_zep->vif_lock->hal_disable->wait lock_rx * nrf70_bh_wq: event_tasklet->lock_rx->disp_scan_done-> disp_scan_res_get_zep-> waiting on vif_lock The traffic triggers recovery (another bug) and conflicts with display scan. Fix by moving scan results processing to system workqueue instead of doing it in the FMAC event callback context, this is how supplicant scan also works. Signed-off-by: Chaitanya Tata <[email protected]>
1 parent 825dea6 commit 9071704

File tree

2 files changed

+25
-6
lines changed

2 files changed

+25
-6
lines changed

drivers/wifi/nrf_wifi/inc/fmac_main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct nrf_wifi_vif_ctx_zep {
5252
uint16_t max_bss_cnt;
5353
unsigned int scan_res_cnt;
5454
struct k_work_delayable scan_timeout_work;
55+
struct k_work disp_scan_res_work;
5556

5657
struct net_eth_addr mac_addr;
5758
int if_type;

drivers/wifi/nrf_wifi/src/fmac_main.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,8 @@ void nrf_wifi_event_proc_scan_done_zep(void *vif_ctx,
171171
switch (vif_ctx_zep->scan_type) {
172172
#ifdef CONFIG_NET_L2_WIFI_MGMT
173173
case SCAN_DISPLAY:
174-
status = nrf_wifi_disp_scan_res_get_zep(vif_ctx_zep);
175-
if (status != NRF_WIFI_STATUS_SUCCESS) {
176-
LOG_ERR("%s: nrf_wifi_disp_scan_res_get_zep failed", __func__);
177-
return;
178-
}
179-
vif_ctx_zep->scan_in_progress = false;
174+
/* Schedule scan result processing in system workqueue to avoid deadlock */
175+
k_work_submit(&vif_ctx_zep->disp_scan_res_work);
180176
break;
181177
#endif /* CONFIG_NET_L2_WIFI_MGMT */
182178
#ifdef CONFIG_NRF70_STA_MODE
@@ -242,6 +238,26 @@ void nrf_wifi_scan_timeout_work(struct k_work *work)
242238
vif_ctx_zep->scan_in_progress = false;
243239
}
244240

241+
void nrf_wifi_disp_scan_res_work_handler(struct k_work *work)
242+
{
243+
struct nrf_wifi_vif_ctx_zep *vif_ctx_zep = NULL;
244+
enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
245+
246+
vif_ctx_zep = CONTAINER_OF(work, struct nrf_wifi_vif_ctx_zep, disp_scan_res_work);
247+
248+
if (!vif_ctx_zep) {
249+
LOG_ERR("%s: vif_ctx_zep is NULL", __func__);
250+
return;
251+
}
252+
253+
status = nrf_wifi_disp_scan_res_get_zep(vif_ctx_zep);
254+
if (status != NRF_WIFI_STATUS_SUCCESS) {
255+
LOG_ERR("%s: nrf_wifi_disp_scan_res_get_zep failed", __func__);
256+
return;
257+
}
258+
vif_ctx_zep->scan_in_progress = false;
259+
}
260+
245261
#ifdef CONFIG_NRF70_STA_MODE
246262
static void nrf_wifi_process_rssi_from_rx(void *vif_ctx,
247263
signed short signal)
@@ -837,6 +853,8 @@ static int nrf_wifi_drv_main_zep(const struct device *dev)
837853
#else
838854
k_work_init_delayable(&vif_ctx_zep->scan_timeout_work,
839855
nrf_wifi_scan_timeout_work);
856+
k_work_init(&vif_ctx_zep->disp_scan_res_work,
857+
nrf_wifi_disp_scan_res_work_handler);
840858
#endif /* CONFIG_NRF70_RADIO_TEST */
841859

842860
k_mutex_init(&rpu_drv_priv_zep.rpu_ctx_zep.rpu_lock);

0 commit comments

Comments
 (0)