Explorar o código

qcacld-3.0: Mutex lock to set direct link config

There is a race condition where profile for direct link is set but
hif link was not yet voted up to prevent suspend. Parallelly,
direct link config is cleared in different context causing hif link
to vote down without being voted up which resulted in crash.
To fix this, create a mutex lock and move all the config set
operations inside the lock.

Change-Id: I80924d9ed52a9889a178b98469be15af0454b022
CRs-Fixed: 3490442
Ananya Gupta hai 1 ano
pai
achega
92a1a945d3

+ 2 - 0
components/dp/core/inc/wlan_dp_priv.h

@@ -515,6 +515,7 @@ struct dp_direct_link_context {
  * @rtpm_tput_policy_ctx: Runtime Tput policy context
  * @txrx_hist: TxRx histogram
  * @bbm_ctx: bus bandwidth manager context
+ * @dp_direct_link_lock: Direct link mutex lock
  * @dp_direct_link_ctx: DP Direct Link context
  * @arp_connectivity_map: ARP connectivity map
  * @rx_wake_lock: rx wake lock
@@ -591,6 +592,7 @@ struct wlan_dp_psoc_context {
 
 	enum RX_OFFLOAD ol_enable;
 #ifdef FEATURE_DIRECT_LINK
+	qdf_mutex_t dp_direct_link_lock;
 	struct dp_direct_link_context *dp_direct_link_ctx;
 #endif
 };

+ 4 - 3
components/dp/core/src/wlan_dp_main.c

@@ -1708,6 +1708,7 @@ QDF_STATUS dp_direct_link_init(struct wlan_dp_psoc_context *dp_ctx)
 		qdf_mem_free(dp_direct_link_ctx);
 		return status;
 	}
+	qdf_mutex_create(&dp_ctx->dp_direct_link_lock);
 
 	dp_ctx->dp_direct_link_ctx = dp_direct_link_ctx;
 
@@ -1724,7 +1725,7 @@ void dp_direct_link_deinit(struct wlan_dp_psoc_context *dp_ctx, bool is_ssr)
 
 	dp_wfds_deinit(dp_ctx->dp_direct_link_ctx, is_ssr);
 	dp_direct_link_refill_ring_deinit(dp_ctx->dp_direct_link_ctx);
-
+	qdf_mutex_destroy(&dp_ctx->dp_direct_link_lock);
 	qdf_mem_free(dp_ctx->dp_direct_link_ctx);
 	dp_ctx->dp_direct_link_ctx = NULL;
 }
@@ -1756,7 +1757,7 @@ QDF_STATUS dp_config_direct_link(struct wlan_dp_intf *dp_intf,
 		return QDF_STATUS_E_EMPTY;
 	}
 
-	qdf_spin_lock(&dp_intf->vdev_lock);
+	qdf_mutex_acquire(&dp_ctx->dp_direct_link_lock);
 	prev_ll = config->low_latency;
 	update_ll = config_direct_link ? enable_low_latency : prev_ll;
 	vote_link = config->config_set ^ config_direct_link;
@@ -1766,7 +1767,6 @@ QDF_STATUS dp_config_direct_link(struct wlan_dp_intf *dp_intf,
 	status = cdp_txrx_set_vdev_param(wlan_psoc_get_dp_handle(dp_ctx->psoc),
 					 dp_intf->intf_id, CDP_VDEV_TX_TO_FW,
 					 vdev_param);
-	qdf_spin_unlock(&dp_intf->vdev_lock);
 
 	if (config_direct_link) {
 		if (vote_link)
@@ -1788,6 +1788,7 @@ QDF_STATUS dp_config_direct_link(struct wlan_dp_intf *dp_intf,
 						htc_get_hif_device(htc_handle));
 		dp_info("Direct link config cleared.");
 	}
+	qdf_mutex_release(&dp_ctx->dp_direct_link_lock);
 
 	return status;
 }