Fix(esp_wifi): Fix race conditions in btm task deletion

This commit is contained in:
Kapil Gupta 2023-07-07 15:39:09 +05:30 committed by jgujarathi
parent 35b6a541de
commit d2f2b952bc

View File

@ -30,6 +30,7 @@ struct wpa_supplicant g_wpa_supp;
static void *s_supplicant_task_hdl = NULL; static void *s_supplicant_task_hdl = NULL;
static void *s_supplicant_evt_queue = NULL; static void *s_supplicant_evt_queue = NULL;
static void *s_supplicant_api_lock = NULL; static void *s_supplicant_api_lock = NULL;
static bool s_supplicant_task_init_done;
#define SUPPLICANT_API_LOCK() os_mutex_lock(s_supplicant_api_lock) #define SUPPLICANT_API_LOCK() os_mutex_lock(s_supplicant_api_lock)
#define SUPPLICANT_API_UNLOCK() os_mutex_unlock(s_supplicant_api_lock) #define SUPPLICANT_API_UNLOCK() os_mutex_unlock(s_supplicant_api_lock)
#define SUPPLICANT_TASK_STACK_SIZE (6144 + TASK_STACK_SIZE_ADD) #define SUPPLICANT_TASK_STACK_SIZE (6144 + TASK_STACK_SIZE_ADD)
@ -145,11 +146,6 @@ static void btm_rrm_task(void *pvParameters)
os_queue_delete(s_supplicant_evt_queue); os_queue_delete(s_supplicant_evt_queue);
s_supplicant_evt_queue = NULL; s_supplicant_evt_queue = NULL;
if (s_supplicant_api_lock) {
os_semphr_delete(s_supplicant_api_lock);
s_supplicant_api_lock = NULL;
}
/* At this point, we completed */ /* At this point, we completed */
os_task_delete(NULL); os_task_delete(NULL);
} }
@ -315,7 +311,10 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
#if defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R) #if defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R)
#ifdef CONFIG_SUPPLICANT_TASK #ifdef CONFIG_SUPPLICANT_TASK
s_supplicant_api_lock = os_recursive_mutex_create(); if (!s_supplicant_api_lock) {
s_supplicant_api_lock = os_recursive_mutex_create();
}
if (!s_supplicant_api_lock) { if (!s_supplicant_api_lock) {
wpa_printf(MSG_ERROR, "%s: failed to create Supplicant API lock", __func__); wpa_printf(MSG_ERROR, "%s: failed to create Supplicant API lock", __func__);
ret = -1; ret = -1;
@ -335,6 +334,7 @@ int esp_supplicant_common_init(struct wpa_funcs *wpa_cb)
ret = -1; ret = -1;
goto err; goto err;
} }
s_supplicant_task_init_done = true;
#endif /* CONFIG_SUPPLICANT_TASK */ #endif /* CONFIG_SUPPLICANT_TASK */
#ifdef CONFIG_WPA_11KV_SUPPORT #ifdef CONFIG_WPA_11KV_SUPPORT
wpas_rrm_reset(wpa_s); wpas_rrm_reset(wpa_s);
@ -380,7 +380,8 @@ void esp_supplicant_common_deinit(void)
} }
#if defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R) #if defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R)
#ifdef CONFIG_SUPPLICANT_TASK #ifdef CONFIG_SUPPLICANT_TASK
if (!s_supplicant_task_hdl && esp_supplicant_post_evt(SIG_SUPPLICANT_DEL_TASK, 0) != 0) { /* We have failed to create task, delete queue and exit */
if (!s_supplicant_task_hdl) {
if (s_supplicant_evt_queue) { if (s_supplicant_evt_queue) {
os_queue_delete(s_supplicant_evt_queue); os_queue_delete(s_supplicant_evt_queue);
s_supplicant_evt_queue = NULL; s_supplicant_evt_queue = NULL;
@ -389,7 +390,14 @@ void esp_supplicant_common_deinit(void)
os_semphr_delete(s_supplicant_api_lock); os_semphr_delete(s_supplicant_api_lock);
s_supplicant_api_lock = NULL; s_supplicant_api_lock = NULL;
} }
} else if (esp_supplicant_post_evt(SIG_SUPPLICANT_DEL_TASK, 0) != 0) {
/* failed to post delete event, just delete event queue and exit */
if (s_supplicant_evt_queue) {
os_queue_delete(s_supplicant_evt_queue);
s_supplicant_evt_queue = NULL;
}
} }
s_supplicant_task_init_done = false;
#endif /* CONFIG_SUPPLICANT_TASK */ #endif /* CONFIG_SUPPLICANT_TASK */
#endif /* defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R) */ #endif /* defined(CONFIG_WPA_11KV_SUPPORT) || defined(CONFIG_IEEE80211R) */
} }
@ -781,27 +789,32 @@ cleanup:
int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data) int esp_supplicant_post_evt(uint32_t evt_id, uint32_t data)
{ {
supplicant_event_t *evt = os_zalloc(sizeof(supplicant_event_t)); supplicant_event_t *evt = os_zalloc(sizeof(supplicant_event_t));
if (evt == NULL) { if (!evt) {
wpa_printf(MSG_ERROR, "Failed to allocated memory");
return -1; return -1;
} }
evt->id = evt_id; evt->id = evt_id;
evt->data = data; evt->data = data;
/* Make sure lock exists before taking it */ /* Make sure lock exists before taking it */
if (s_supplicant_api_lock) { SUPPLICANT_API_LOCK();
SUPPLICANT_API_LOCK();
} else { /* Make sure no event can be sent when deletion event is sent or task not initialized */
if (!s_supplicant_task_init_done) {
SUPPLICANT_API_UNLOCK();
os_free(evt); os_free(evt);
return -1; return -1;
} }
if (os_queue_send(s_supplicant_evt_queue, &evt, os_task_ms_to_tick(10)) != TRUE) { if (os_queue_send(s_supplicant_evt_queue, &evt, os_task_ms_to_tick(10)) != TRUE) {
SUPPLICANT_API_UNLOCK(); SUPPLICANT_API_UNLOCK();
os_free(evt); os_free(evt);
return -1; return -1;
} }
if (evt_id != SIG_SUPPLICANT_DEL_TASK) { if (evt_id == SIG_SUPPLICANT_DEL_TASK) {
SUPPLICANT_API_UNLOCK(); s_supplicant_task_init_done = false;
} }
SUPPLICANT_API_UNLOCK();
return 0; return 0;
} }
#endif /* CONFIG_SUPPLICANT_TASK */ #endif /* CONFIG_SUPPLICANT_TASK */