From 01abdac6a063001f100052ab657c244caee60659 Mon Sep 17 00:00:00 2001 From: Abhijit Pradhan Date: Tue, 24 Jul 2018 18:03:50 +0530 Subject: [PATCH] qcacmn: Free dfs timers during wifi driver unload All the dfs timers that are initialized with qdf_timer_init() must be freed with qdf_timer_free() to avoid the timer leaks. Change-Id: I5425f0a84d0e252e3a1dc9b835f1b655fe79a691 CRs-Fixed: 2262081 --- umac/dfs/core/src/dfs.h | 23 +++++++++++++ umac/dfs/core/src/dfs_filter_init.h | 12 +++++++ umac/dfs/core/src/dfs_partial_offload_radar.h | 12 +++++++ umac/dfs/core/src/dfs_zero_cac.h | 12 +++++++ umac/dfs/core/src/misc/dfs.c | 25 ++++++++++++++- umac/dfs/core/src/misc/dfs_cac.c | 8 +++++ umac/dfs/core/src/misc/dfs_filter_init.c | 15 ++++++++- umac/dfs/core/src/misc/dfs_nol.c | 23 +++++++------ umac/dfs/core/src/misc/dfs_zero_cac.c | 32 +++++++++++++++++-- .../dispatcher/src/wlan_dfs_init_deinit_api.c | 1 - 10 files changed, 147 insertions(+), 16 deletions(-) diff --git a/umac/dfs/core/src/dfs.h b/umac/dfs/core/src/dfs.h index 26e65af73035..b857e7412d2f 100644 --- a/umac/dfs/core/src/dfs.h +++ b/umac/dfs/core/src/dfs.h @@ -1383,6 +1383,12 @@ void dfs_nol_update(struct wlan_dfs *dfs); */ void dfs_nol_timer_cleanup(struct wlan_dfs *dfs); +/** + * dfs_nol_timer_free() - Free NOL timer. + * @dfs: Pointer to wlan_dfs structure. + */ +void dfs_nol_timer_free(struct wlan_dfs *dfs); + /** * dfs_nol_workqueue_cleanup() - Flushes NOL workqueue. * @dfs: Pointer to wlan_dfs structure. @@ -2013,6 +2019,12 @@ void dfs_cac_attach(struct wlan_dfs *dfs); */ void dfs_cac_timer_reset(struct wlan_dfs *dfs); +/** + * dfs_cac_timer_free() - Free dfs cac timers. + * @dfs: Pointer to wlan_dfs structure. + */ +void dfs_cac_timer_free(struct wlan_dfs *dfs); + /** * dfs_nol_timer_init() - Initialize NOL timers. * @dfs: Pointer to wlan_dfs structure. @@ -2332,4 +2344,15 @@ void dfs_task_testtimer_reset(struct wlan_dfs *dfs); */ bool dfs_freq_is_in_nol(struct wlan_dfs *dfs, uint32_t freq); +/** + * dfs_task_testtimer_free() - Free dfs test timer. + * @dfs: Pointer to wlan_dfs structure. + */ +void dfs_task_testtimer_free(struct wlan_dfs *dfs); + +/** + * dfs_timer_free() - Free dfs timers. + * @dfs: Pointer to wlan_dfs structure. + */ +void dfs_timer_free(struct wlan_dfs *dfs); #endif /* _DFS_H_ */ diff --git a/umac/dfs/core/src/dfs_filter_init.h b/umac/dfs/core/src/dfs_filter_init.h index e8cbf71e7907..657a9c35246a 100644 --- a/umac/dfs/core/src/dfs_filter_init.h +++ b/umac/dfs/core/src/dfs_filter_init.h @@ -76,4 +76,16 @@ static void dfs_main_timer_reset(struct wlan_dfs *dfs) } #endif +/** + * dfs_main_timer_free() - Free dfs timers. + * @dfs: Pointer to wlan_dfs structure. + */ +#if defined(WLAN_DFS_DIRECT_ATTACH) || defined(WLAN_DFS_PARTIAL_OFFLOAD) +void dfs_main_timer_free(struct wlan_dfs *dfs); +#else +static void dfs_main_timer_free(struct wlan_dfs *dfs) +{ +} +#endif + #endif /* _DFS_FILTER_INIT_H_ */ diff --git a/umac/dfs/core/src/dfs_partial_offload_radar.h b/umac/dfs/core/src/dfs_partial_offload_radar.h index 012f4275cb7b..6743efc9de99 100644 --- a/umac/dfs/core/src/dfs_partial_offload_radar.h +++ b/umac/dfs/core/src/dfs_partial_offload_radar.h @@ -67,6 +67,18 @@ static inline void dfs_host_wait_timer_init(struct wlan_dfs *dfs) } #endif +/** + * dfs_host_wait_timer_free() - Free dfs host status wait timer. + * @dfs: Pointer to wlan_dfs structure. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_host_wait_timer_free(struct wlan_dfs *dfs); +#else +static inline void dfs_host_wait_timer_free(struct wlan_dfs *dfs) +{ +} +#endif + /** * dfs_set_override_status_timeout() - Change the dfs host status timeout. * @dfs: Pointer to wlan_dfs structure. diff --git a/umac/dfs/core/src/dfs_zero_cac.h b/umac/dfs/core/src/dfs_zero_cac.h index e708abdf519f..74b361d036d9 100644 --- a/umac/dfs/core/src/dfs_zero_cac.h +++ b/umac/dfs/core/src/dfs_zero_cac.h @@ -184,6 +184,18 @@ static inline void dfs_zero_cac_reset(struct wlan_dfs *dfs) } #endif +/** + * dfs_zero_cac_timer_free() - Free Zero cac DFS variables. + * @dfs: Pointer to wlan_dfs structure. + */ +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) +void dfs_zero_cac_timer_free(struct wlan_dfs *dfs); +#else +static inline void dfs_zero_cac_timer_free(struct wlan_dfs *dfs) +{ +} +#endif + /** * dfs_is_precac_done() - Is precac done. * @dfs: Pointer to wlan_dfs structure. diff --git a/umac/dfs/core/src/misc/dfs.c b/umac/dfs/core/src/misc/dfs.c index 9900258ee27a..537081ebc56e 100644 --- a/umac/dfs/core/src/misc/dfs.c +++ b/umac/dfs/core/src/misc/dfs.c @@ -31,6 +31,7 @@ #include "../dfs_full_offload.h" #include "wlan_dfs_utils_api.h" #include "../dfs_etsi_precac.h" +#include "../dfs_partial_offload_radar.h" /** * dfs_testtimer_task() - Sends CSA in the current channel. @@ -139,11 +140,17 @@ void dfs_stop(struct wlan_dfs *dfs) void dfs_task_testtimer_reset(struct wlan_dfs *dfs) { if (dfs->wlan_dfstest) { - qdf_timer_stop(&dfs->wlan_dfstesttimer); + qdf_timer_sync_cancel(&dfs->wlan_dfstesttimer); dfs->wlan_dfstest = 0; } } +void dfs_task_testtimer_free(struct wlan_dfs *dfs) +{ + qdf_timer_free(&dfs->wlan_dfstesttimer); + dfs->wlan_dfstest = 0; +} + void dfs_reset(struct wlan_dfs *dfs) { if (!dfs) { @@ -155,13 +162,29 @@ void dfs_reset(struct wlan_dfs *dfs) dfs_zero_cac_reset(dfs); if (!dfs->dfs_is_offload_enabled) { dfs_main_timer_reset(dfs); + dfs_host_wait_timer_reset(dfs); dfs->dfs_event_log_count = 0; } dfs_task_testtimer_reset(dfs); } +void dfs_timer_free(struct wlan_dfs *dfs) +{ + dfs_cac_timer_free(dfs); + dfs_zero_cac_timer_free(dfs); + + if (!dfs->dfs_is_offload_enabled) { + dfs_main_timer_free(dfs); + dfs_host_wait_timer_free(dfs); + } + + dfs_task_testtimer_free(dfs); + dfs_nol_timer_free(dfs); +} + void dfs_detach(struct wlan_dfs *dfs) { + dfs_timer_free(dfs); if (!dfs->dfs_is_offload_enabled) dfs_main_detach(dfs); dfs_etsi_precac_detach(dfs); diff --git a/umac/dfs/core/src/misc/dfs_cac.c b/umac/dfs/core/src/misc/dfs_cac.c index bfe4a8026523..88b9b6dd6744 100644 --- a/umac/dfs/core/src/misc/dfs_cac.c +++ b/umac/dfs/core/src/misc/dfs_cac.c @@ -186,6 +186,14 @@ void dfs_cac_timer_reset(struct wlan_dfs *dfs) } +void dfs_cac_timer_free(struct wlan_dfs *dfs) +{ + qdf_timer_free(&dfs->dfs_cac_timer); + + qdf_timer_free(&dfs->dfs_cac_valid_timer); + dfs->dfs_cac_valid = 0; +} + int dfs_is_ap_cac_timer_running(struct wlan_dfs *dfs) { return dfs->dfs_cac_timer_running; diff --git a/umac/dfs/core/src/misc/dfs_filter_init.c b/umac/dfs/core/src/misc/dfs_filter_init.c index d753459bb094..41aa44d0e8da 100644 --- a/umac/dfs/core/src/misc/dfs_filter_init.c +++ b/umac/dfs/core/src/misc/dfs_filter_init.c @@ -219,11 +219,24 @@ bad1: void dfs_main_timer_reset(struct wlan_dfs *dfs) { if (dfs->wlan_radar_tasksched) { - qdf_timer_stop(&dfs->wlan_dfs_task_timer); + qdf_timer_sync_cancel(&dfs->wlan_dfs_task_timer); dfs->wlan_radar_tasksched = 0; } } +void dfs_main_timer_free(struct wlan_dfs *dfs) +{ + qdf_timer_free(&dfs->wlan_dfs_task_timer); + dfs->wlan_radar_tasksched = 0; +} + +#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST) +void dfs_host_wait_timer_free(struct wlan_dfs *dfs) +{ + qdf_timer_free(&dfs->dfs_host_wait_timer); +} +#endif + void dfs_main_detach(struct wlan_dfs *dfs) { int n, empty; diff --git a/umac/dfs/core/src/misc/dfs_nol.c b/umac/dfs/core/src/misc/dfs_nol.c index 42df95d70dc0..f94fea714f63 100644 --- a/umac/dfs/core/src/misc/dfs_nol.c +++ b/umac/dfs/core/src/misc/dfs_nol.c @@ -126,6 +126,7 @@ static void dfs_nol_elem_free_work_cb(void *context) tmp_nol_entry) { TAILQ_REMOVE(&dfs->dfs_nol_free_list, nol_entry, nolelem_list); + qdf_timer_free(&nol_entry->nol_timer); qdf_mem_free(nol_entry); } WLAN_DFSNOL_UNLOCK(dfs); @@ -159,6 +160,11 @@ void dfs_nol_detach(struct wlan_dfs *dfs) WLAN_DFSNOL_LOCK_DESTROY(dfs); } +void dfs_nol_timer_free(struct wlan_dfs *dfs) +{ + qdf_timer_free(&dfs->dfs_nol_timer); +} + /** * dfs_nol_delete() - Delete the given frequency/chwidth from the NOL. * @dfs: Pointer to wlan_dfs structure. @@ -539,16 +545,13 @@ void dfs_nol_timer_cleanup(struct wlan_dfs *dfs) while (nol) { dfs->dfs_nol = nol->nol_next; dfs->dfs_nol_count--; - - if (!qdf_timer_stop(&nol->nol_timer)) { - /* - * Unlock is required so that when we sync with the - * nol_timeout timer we do not run into deadlock. - */ - WLAN_DFSNOL_UNLOCK(dfs); - qdf_timer_sync_cancel(&(nol->nol_timer)); - WLAN_DFSNOL_LOCK(dfs); - } + /* + * Unlock is required so that when we sync with the + * nol_timeout timer we do not run into deadlock. + */ + WLAN_DFSNOL_UNLOCK(dfs); + qdf_timer_free(&nol->nol_timer); + WLAN_DFSNOL_LOCK(dfs); qdf_mem_free(nol); nol = dfs->dfs_nol; diff --git a/umac/dfs/core/src/misc/dfs_zero_cac.c b/umac/dfs/core/src/misc/dfs_zero_cac.c index a2edffde5d23..17aa18079be0 100644 --- a/umac/dfs/core/src/misc/dfs_zero_cac.c +++ b/umac/dfs/core/src/misc/dfs_zero_cac.c @@ -101,7 +101,7 @@ void dfs_zero_cac_reset(struct wlan_dfs *dfs) dfs_get_override_precac_timeout(dfs, &(dfs->dfs_precac_timeout_override)); - qdf_timer_stop(&dfs->dfs_precac_timer); + qdf_timer_sync_cancel(&dfs->dfs_precac_timer); dfs->dfs_precac_primary_freq = 0; dfs->dfs_precac_secondary_freq = 0; @@ -111,9 +111,35 @@ void dfs_zero_cac_reset(struct wlan_dfs *dfs) &dfs->dfs_precac_nol_list, pe_list, tmp_precac_entry) { - qdf_timer_stop(&precac_entry->precac_nol_timer); + qdf_timer_free(&precac_entry->precac_nol_timer); TAILQ_REMOVE(&dfs->dfs_precac_required_list, - precac_entry, pe_list); + precac_entry, pe_list); + qdf_mem_free(precac_entry); + } + PRECAC_LIST_UNLOCK(dfs); +} + +void dfs_zero_cac_timer_free(struct wlan_dfs *dfs) +{ + struct dfs_precac_entry *tmp_precac_entry, *precac_entry; + + dfs_get_override_precac_timeout(dfs, + &dfs->dfs_precac_timeout_override); + + qdf_timer_free(&dfs->dfs_precac_timer); + + dfs->dfs_precac_primary_freq = 0; + dfs->dfs_precac_secondary_freq = 0; + + PRECAC_LIST_LOCK(dfs); + if (!TAILQ_EMPTY(&dfs->dfs_precac_nol_list)) + TAILQ_FOREACH_SAFE(precac_entry, + &dfs->dfs_precac_nol_list, + pe_list, + tmp_precac_entry) { + qdf_timer_free(&precac_entry->precac_nol_timer); + TAILQ_REMOVE(&dfs->dfs_precac_required_list, + precac_entry, pe_list); qdf_mem_free(precac_entry); } PRECAC_LIST_UNLOCK(dfs); diff --git a/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c b/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c index 8f562b22cd8a..91cedc396c05 100644 --- a/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c +++ b/umac/dfs/dispatcher/src/wlan_dfs_init_deinit_api.c @@ -400,7 +400,6 @@ QDF_STATUS wlan_dfs_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev, WLAN_UMAC_COMP_DFS, (void *)dfs); - dfs_reset(dfs); dfs_detach(dfs); dfs->dfs_pdev_obj = NULL; dfs_destroy_object(dfs);