From 787c7cdb439665df507b6d4639b5e2ee39fa7d5f Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Mon, 13 May 2019 13:41:31 +0800 Subject: [PATCH] qcacmn: Free serial cmd before its timer when rmmod Rmmod process: wlan_hdd_pld_remove --> hdd_stop_adapter --> hdd_vdev_destroy --> WLAN_SER_CMD_DEL_STA_SESSION (25) cmd queued --> PLD_FW_DOWN (will complete wait event as part of qdf_complete_wait_events) --> hdd_wlan_stop_modules --> cds_disable --> dispatcher_psoc_disable --> wlan_serialization_psoc_disable --> wlan_serialization_timer_destroy --> umac_stop --> csr_stop --> wlan_ser_cancel_non_scan_cmd -> check if timer is present but th timer are already destroyed, so assert. Move wlan_serialization_purge_cmd_list into converged API file to be shared by MCC and WIN. Change-Id: Iad557e4a05d682c257be0c39049c52950e5eb530 CRs-Fixed: 2451058 --- .../inc/wlan_serialization_api.h | 16 ++++++++ .../src/wlan_serialization_api.c | 41 +++++++++++++++++++ .../src/wlan_serialization_main.c | 6 +++ 3 files changed, 63 insertions(+) diff --git a/umac/cmn_services/serialization/inc/wlan_serialization_api.h b/umac/cmn_services/serialization/inc/wlan_serialization_api.h index a22337c8b557..a7e19d092111 100644 --- a/umac/cmn_services/serialization/inc/wlan_serialization_api.h +++ b/umac/cmn_services/serialization/inc/wlan_serialization_api.h @@ -604,4 +604,20 @@ QDF_STATUS wlan_ser_validate_umac_cmd(struct wlan_objmgr_vdev *vdev, enum wlan_serialization_cmd_type cmd_type, wlan_ser_umac_cmd_cb umac_cmd_cb); + +/** + * wlan_serialization_purge_all_pdev_cmd() - purge all command for given pdev + * @pdev: objmgr pdev pointer + * + * Return: void + */ +void wlan_serialization_purge_all_pdev_cmd(struct wlan_objmgr_pdev *pdev); + +/** + * wlan_serialization_purge_all_cmd() - purge all command for psoc + * @psoc: objmgr psoc pointer + * + * Return: void + */ +void wlan_serialization_purge_all_cmd(struct wlan_objmgr_psoc *psoc); #endif diff --git a/umac/cmn_services/serialization/src/wlan_serialization_api.c b/umac/cmn_services/serialization/src/wlan_serialization_api.c index de9ae64ade2e..bebc087fd5b8 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_api.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_api.c @@ -781,3 +781,44 @@ wlan_ser_validate_umac_cmd(struct wlan_objmgr_vdev *vdev, return status; } + +void wlan_serialization_purge_all_pdev_cmd(struct wlan_objmgr_pdev *pdev) +{ + struct wlan_ser_pdev_obj *ser_pdev_obj; + + if (!pdev) { + ser_err("NULL pdev"); + return; + } + + ser_pdev_obj = wlan_serialization_get_pdev_obj(pdev); + if (!ser_pdev_obj) { + ser_err("invalid ser_pdev_obj"); + return; + } + + wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, + WLAN_SER_CMD_SCAN, false); + wlan_ser_cancel_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, + WLAN_SER_CMD_SCAN, true); + wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, + WLAN_SER_CMD_NONSCAN, false); + wlan_ser_cancel_non_scan_cmd(ser_pdev_obj, pdev, NULL, NULL, + WLAN_SER_CMD_NONSCAN, true); +} + +static inline +void wlan_ser_purge_pdev_cmd_cb(struct wlan_objmgr_psoc *psoc, + void *object, void *arg) +{ + struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object; + + wlan_serialization_purge_all_pdev_cmd(pdev); +} + +void wlan_serialization_purge_all_cmd(struct wlan_objmgr_psoc *psoc) +{ + wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP, + wlan_ser_purge_pdev_cmd_cb, NULL, 1, + WLAN_SERIALIZATION_ID); +} diff --git a/umac/cmn_services/serialization/src/wlan_serialization_main.c b/umac/cmn_services/serialization/src/wlan_serialization_main.c index dbb7fb33355c..f663a8d096c0 100644 --- a/umac/cmn_services/serialization/src/wlan_serialization_main.c +++ b/umac/cmn_services/serialization/src/wlan_serialization_main.c @@ -41,6 +41,12 @@ QDF_STATUS wlan_serialization_psoc_disable(struct wlan_objmgr_psoc *psoc) ser_err("invalid ser_soc_obj"); goto error; } + + /* + * purge all serialization command if there are any pending to make + * sure memory and vdev ref are freed. + */ + wlan_serialization_purge_all_cmd(psoc); /* clean up all timers before exiting */ status = wlan_serialization_cleanup_all_timers(ser_soc_obj); if (status != QDF_STATUS_SUCCESS)