From 62fb09b241371aee3a5da0a42b3d958632aa49e5 Mon Sep 17 00:00:00 2001 From: Abhishek Singh Date: Mon, 29 Jun 2020 17:53:28 +0530 Subject: [PATCH] qcacmn: Fix race between ser psoc close and vdev destroy handler In wlan_serialization_psoc_disable the timers are freed without holding lock and at the same time the wlan_serialization_cleanup_vdev_timers from vdev destroy handler is accessing the timers, this result in cleanup_vdev_timers accessing freed timer memory resulting in assert. Fix is to free timer memory while holding timer lock. Also as the lock can be used by vdev delete handler after freeing in psoc_disable, move the init and deinit of the lock to psoc create and destroy handlers respectively. Change-Id: Idf822a91022de6b51c7ee1895f71b6fb94fedd72 CRs-Fixed: 2721064 --- .../serialization/src/wlan_serialization_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/umac/cmn_services/serialization/src/wlan_serialization_main.c b/umac/cmn_services/serialization/src/wlan_serialization_main.c index a6ece3d83193..7877376bce95 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_main.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_main.c @@ -52,11 +52,12 @@ QDF_STATUS wlan_serialization_psoc_disable(struct wlan_objmgr_psoc *psoc) if (status != QDF_STATUS_SUCCESS) ser_err("ser cleanning up all timer failed"); + /* Use lock to free to avoid any race where timer is still in use */ + wlan_serialization_acquire_lock(&ser_soc_obj->timer_lock); qdf_mem_free(ser_soc_obj->timers); ser_soc_obj->timers = NULL; ser_soc_obj->max_active_cmds = 0; - - wlan_serialization_destroy_lock(&ser_soc_obj->timer_lock); + wlan_serialization_release_lock(&ser_soc_obj->timer_lock); error: return status; } @@ -87,7 +88,6 @@ QDF_STATUS wlan_serialization_psoc_enable(struct wlan_objmgr_psoc *psoc) goto error; } - wlan_serialization_create_lock(&ser_soc_obj->timer_lock); status = QDF_STATUS_SUCCESS; error: @@ -127,6 +127,7 @@ static QDF_STATUS wlan_serialization_psoc_create_handler( ser_err("Obj attach failed"); goto error; } + wlan_serialization_create_lock(&soc_ser_obj->timer_lock); ser_debug("ser psoc obj created"); status = QDF_STATUS_SUCCESS; @@ -331,6 +332,7 @@ wlan_serialization_psoc_destroy_handler(struct wlan_objmgr_psoc *psoc, if (status != QDF_STATUS_SUCCESS) ser_err("ser psoc private obj detach failed"); + wlan_serialization_destroy_lock(&ser_soc_obj->timer_lock); ser_debug("ser psoc obj deleted with status %d", status); qdf_mem_free(ser_soc_obj);