瀏覽代碼

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
Abhijit Pradhan 6 年之前
父節點
當前提交
01abdac6a0

+ 23 - 0
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_ */

+ 12 - 0
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_ */

+ 12 - 0
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.

+ 12 - 0
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.

+ 24 - 1
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);

+ 8 - 0
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;

+ 14 - 1
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;

+ 13 - 10
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;

+ 29 - 3
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);

+ 0 - 1
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);