Переглянути джерело

qcacmn: Dynamically allocate memory for work sta_ap_intf_check_work

To handle back to back scheduling of sta_ap_intf_check_work, allocate the
memory used by the work dynamically.

Change-Id: Ibbcfafb2fadd2de1cca44086f9335dca86641f50
CRs-Fixed: 2070220
Tushnim Bhattacharyya 7 роки тому
батько
коміт
d3c96deba9

+ 52 - 18
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -598,14 +598,15 @@ static bool policy_mgr_is_restart_sap_allowed(
 	uint32_t mcc_to_scc_switch)
 {
 	if ((mcc_to_scc_switch == QDF_MCC_TO_SCC_SWITCH_DISABLE) ||
-	    !(policy_mgr_concurrent_open_sessions_running(psoc) &&
-	      ((policy_mgr_get_concurrency_mode(psoc) ==
-	       (QDF_STA_MASK | QDF_SAP_MASK)) ||
-	      (policy_mgr_get_concurrency_mode(psoc) ==
-	       (QDF_STA_MASK | QDF_P2P_GO_MASK))))) {
+		!policy_mgr_concurrent_open_sessions_running(psoc) ||
+		!((policy_mgr_get_concurrency_mode(psoc) ==
+			(QDF_STA_MASK | QDF_SAP_MASK)) ||
+		(policy_mgr_get_concurrency_mode(psoc) ==
+			(QDF_STA_MASK | QDF_P2P_GO_MASK)))) {
 		policy_mgr_err("MCC switch disabled or not concurrent STA/SAP, STA/GO");
 		return false;
 	}
+
 	return true;
 }
 
@@ -649,18 +650,30 @@ bool policy_mgr_is_safe_channel(struct wlan_objmgr_psoc *psoc,
  */
 void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
 {
-	struct wlan_objmgr_psoc *psoc =
-		(struct wlan_objmgr_psoc *) data;
-	struct policy_mgr_psoc_priv_obj *pm_ctx;
+	struct wlan_objmgr_psoc *psoc;
+	struct policy_mgr_psoc_priv_obj *pm_ctx = NULL;
+	struct sta_ap_intf_check_work_ctx *work_info = NULL;
 	uint32_t mcc_to_scc_switch;
 	QDF_STATUS status;
 	uint8_t channel, sec_ch;
 	uint8_t operating_channel, vdev_id;
 
+	work_info = (struct sta_ap_intf_check_work_ctx *) data;
+	if (!work_info) {
+		policy_mgr_err("Invalid work_info");
+		goto end;
+	}
+
+	psoc = work_info->psoc;
+	if (!psoc) {
+		policy_mgr_err("Invalid psoc");
+		goto end;
+	}
+
 	pm_ctx = policy_mgr_get_context(psoc);
 	if (!pm_ctx) {
 		policy_mgr_err("Invalid context");
-		return;
+		goto end;
 	}
 	mcc_to_scc_switch =
 		policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc);
@@ -669,7 +682,7 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
 		policy_mgr_concurrent_open_sessions_running(psoc));
 
 	if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch))
-		return;
+		goto end;
 
 	if (policy_mgr_get_mode_specific_conn_info(psoc,
 						   &operating_channel,
@@ -685,12 +698,12 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
 				 operating_channel);
 	} else {
 		policy_mgr_err("Could not retrieve SAP/GO operating channel&vdevid");
-		return;
+		goto end;
 	}
 
 	if (!pm_ctx->hdd_cbacks.wlan_hdd_get_channel_for_sap_restart) {
 		policy_mgr_err("SAP restart get channel callback in NULL");
-		return;
+		goto end;
 	}
 	qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
 	status = pm_ctx->hdd_cbacks.
@@ -699,11 +712,17 @@ void policy_mgr_check_sta_ap_concurrent_ch_intf(void *data)
 	qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
 	if (status != QDF_STATUS_SUCCESS) {
 		policy_mgr_err("Failed to switch SAP channel");
-		return;
+		goto end;
 	}
 
 	policy_mgr_info("SAP restarts due to MCC->SCC switch, old chan :%d new chan: %d",
 			operating_channel, channel);
+end:
+	if (work_info) {
+		qdf_mem_free(work_info);
+		if (pm_ctx)
+			pm_ctx->sta_ap_intf_check_work_info = NULL;
+	}
 }
 
 static bool policy_mgr_valid_sta_channel_check(struct wlan_objmgr_psoc *psoc,
@@ -846,15 +865,30 @@ void policy_mgr_check_concurrent_intf_and_restart_sap(
 		policy_mgr_mcc_to_scc_switch_mode_in_user_cfg(psoc);
 	policy_mgr_info("MCC to SCC switch: %d chan: %d",
 			mcc_to_scc_switch, operating_channel);
+
+	if (!policy_mgr_is_restart_sap_allowed(psoc, mcc_to_scc_switch)) {
+		policy_mgr_debug(
+			"No action taken at check_concurrent_intf_and_restart_sap");
+		return;
+	}
+
 	if ((mcc_to_scc_switch != QDF_MCC_TO_SCC_SWITCH_DISABLE) &&
 		policy_mgr_valid_sta_channel_check(psoc,
 					 operating_channel)
-	    ) {
-		qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work,
+		&& !pm_ctx->sta_ap_intf_check_work_info) {
+		struct sta_ap_intf_check_work_ctx *work_info;
+		work_info = qdf_mem_malloc(
+			sizeof(struct sta_ap_intf_check_work_ctx));
+		pm_ctx->sta_ap_intf_check_work_info = work_info;
+		if (work_info) {
+			work_info->psoc = psoc;
+			qdf_create_work(0, &pm_ctx->sta_ap_intf_check_work,
 				policy_mgr_check_sta_ap_concurrent_ch_intf,
-				psoc);
-		qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work);
-		policy_mgr_info("Checking for Concurrent Change interference");
+				work_info);
+			qdf_sched_work(0, &pm_ctx->sta_ap_intf_check_work);
+			policy_mgr_info(
+				"Checking for Concurrent Change interference");
+		}
 	}
 }
 #endif /* FEATURE_WLAN_MCC_TO_SCC_SWITCH */

+ 37 - 26
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_i.h

@@ -184,6 +184,15 @@ extern enum policy_mgr_conc_next_action
 	(*policy_mgr_get_current_pref_hw_mode_ptr)
 	(struct wlan_objmgr_psoc *psoc);
 
+/**
+ * struct sta_ap_intf_check_work_ctx - sta_ap_intf_check_work
+ * related info
+ * @psoc: pointer to PSOC object information
+ */
+struct sta_ap_intf_check_work_ctx {
+	struct wlan_objmgr_psoc *psoc;
+};
+
 /**
  * struct policy_mgr_psoc_priv_obj - Policy manager private data
  * @psoc: pointer to PSOC object information
@@ -229,34 +238,36 @@ extern enum policy_mgr_conc_next_action
  *      value from INI
  * @unsafe_channel_list: LTE coex channel avoidance list
  * @unsafe_channel_count: LTE coex channel avoidance list count
+ * @sta_ap_intf_check_work_info: Info related to sta_ap_intf_check_work
  */
 struct policy_mgr_psoc_priv_obj {
-		struct wlan_objmgr_psoc *psoc;
-		struct wlan_objmgr_pdev *pdev;
-		qdf_event_t connection_update_done_evt;
-		qdf_mutex_t qdf_conc_list_lock;
-		qdf_mc_timer_t dbs_opportunistic_timer;
-		struct policy_mgr_hdd_cbacks hdd_cbacks;
-		struct policy_mgr_sme_cbacks sme_cbacks;
-		struct policy_mgr_wma_cbacks wma_cbacks;
-		struct policy_mgr_tdls_cbacks tdls_cbacks;
-		struct policy_mgr_cdp_cbacks cdp_cbacks;
-		uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN];
-		uint32_t sap_mandatory_channels_len;
-		bool do_hw_mode_change;
-		uint32_t concurrency_mode;
-		uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE];
-		uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE];
-		qdf_work_t sta_ap_intf_check_work;
-		uint32_t num_dbs_hw_modes;
-		struct dbs_hw_mode_info hw_mode;
-		uint32_t old_hw_mode_index;
-		uint32_t new_hw_mode_index;
-		struct dual_mac_config dual_mac_cfg;
-		uint32_t hw_mode_change_in_progress;
-		struct policy_mgr_user_cfg user_cfg;
-		uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN];
-		uint16_t unsafe_channel_count;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_objmgr_pdev *pdev;
+	qdf_event_t connection_update_done_evt;
+	qdf_mutex_t qdf_conc_list_lock;
+	qdf_mc_timer_t dbs_opportunistic_timer;
+	struct policy_mgr_hdd_cbacks hdd_cbacks;
+	struct policy_mgr_sme_cbacks sme_cbacks;
+	struct policy_mgr_wma_cbacks wma_cbacks;
+	struct policy_mgr_tdls_cbacks tdls_cbacks;
+	struct policy_mgr_cdp_cbacks cdp_cbacks;
+	uint8_t sap_mandatory_channels[QDF_MAX_NUM_CHAN];
+	uint32_t sap_mandatory_channels_len;
+	bool do_hw_mode_change;
+	uint32_t concurrency_mode;
+	uint8_t no_of_open_sessions[QDF_MAX_NO_OF_MODE];
+	uint8_t no_of_active_sessions[QDF_MAX_NO_OF_MODE];
+	qdf_work_t sta_ap_intf_check_work;
+	uint32_t num_dbs_hw_modes;
+	struct dbs_hw_mode_info hw_mode;
+	uint32_t old_hw_mode_index;
+	uint32_t new_hw_mode_index;
+	struct dual_mac_config dual_mac_cfg;
+	uint32_t hw_mode_change_in_progress;
+	struct policy_mgr_user_cfg user_cfg;
+	uint16_t unsafe_channel_list[QDF_MAX_NUM_CHAN];
+	uint16_t unsafe_channel_count;
+	struct sta_ap_intf_check_work_ctx *sta_ap_intf_check_work_info;
 };
 
 /**

+ 6 - 0
umac/cmn_services/policy_mgr/src/wlan_policy_mgr_init_deinit.c

@@ -364,6 +364,12 @@ QDF_STATUS policy_mgr_psoc_close(struct wlan_objmgr_psoc *psoc)
 		policy_mgr_info("HW list is freed");
 	}
 
+	if (pm_ctx->sta_ap_intf_check_work_info) {
+		qdf_cancel_work(0, &pm_ctx->sta_ap_intf_check_work);
+		qdf_mem_free(pm_ctx->sta_ap_intf_check_work_info);
+		pm_ctx->sta_ap_intf_check_work_info = NULL;
+	}
+
 	return QDF_STATUS_SUCCESS;
 }