Forráskód Böngészése

qcacld-3.0: Prevent runtime suspend untill clean-up completes

qcacld-2.0 to qcacld-3.0 propagation

When runtime suspend fails because of wma_suspend_req() not
completing in time, PM runtime workqueue posts resume request to
MC thread to clean-up. If MC thread is busy or slow in processing
resume request and after the timeout Runtime PM framework posts
another suspend request then there may be race condition between
MC thread processing resume request (Or even suspend request) and
Runtime PM workqueue posting subsequent suspend request.
Synchronize subsequent suspend request by not allowing the
runtime suspend till resume requests completes in MC thread
context.

Change-Id: Ie9aaf72fbced41f8d23640b9032a3c2236dc6826
CRs-fixed: 921373
Houston Hoffman 9 éve
szülő
commit
c45db899eb
3 módosított fájl, 25 hozzáadás és 2 törlés
  1. 1 0
      core/wma/inc/wma.h
  2. 19 2
      core/wma/src/wma_features.c
  3. 5 0
      core/wma/src/wma_main.c

+ 1 - 0
core/wma/inc/wma.h

@@ -1351,6 +1351,7 @@ typedef struct {
 		tpSirBssDescription  bss_desc_ptr);
 	qdf_wake_lock_t wmi_cmd_rsp_wake_lock;
 	qdf_runtime_lock_t wmi_cmd_rsp_runtime_lock;
+	qdf_runtime_lock_t wma_runtime_resume_lock;
 	uint32_t fine_time_measurement_cap;
 	struct wma_ini_config ini_config;
 } t_wma_handle, *tp_wma_handle;

+ 19 - 2
core/wma/src/wma_features.c

@@ -2983,6 +2983,9 @@ QDF_STATUS wma_resume_req(tp_wma_handle wma, enum qdf_suspend_type type)
 
 	wmi_set_runtime_pm_inprogress(wma->wmi_handle, false);
 
+	if (type == QDF_RUNTIME_SUSPEND)
+		qdf_runtime_pm_allow_suspend(wma->wma_runtime_resume_lock);
+
 	return QDF_STATUS_SUCCESS;
 }
 
@@ -4881,10 +4884,22 @@ void wma_send_regdomain_info_to_fw(uint32_t reg_dmn, uint16_t regdmn2G,
 static QDF_STATUS wma_post_runtime_resume_msg(WMA_HANDLE handle)
 {
 	cds_msg_t resume_msg;
+	QDF_STATUS status;
+	tp_wma_handle wma = (tp_wma_handle) handle;
+
+	qdf_runtime_pm_prevent_suspend(wma->wma_runtime_resume_lock);
 
 	resume_msg.bodyptr = NULL;
 	resume_msg.type    = WMA_RUNTIME_PM_RESUME_IND;
-	return cds_mq_post_message(QDF_MODULE_ID_WMA, &resume_msg);
+
+	status = cds_mq_post_message(QDF_MODULE_ID_WMA, &resume_msg);
+
+	if (!QDF_IS_STATUS_SUCCESS(status)) {
+		WMA_LOGE("Failed to post Runtime PM Resume IND to VOS");
+		qdf_runtime_pm_allow_suspend(wma->wma_runtime_resume_lock);
+	}
+
+	return status;
 }
 
 /**
@@ -4915,11 +4930,13 @@ static QDF_STATUS wma_post_runtime_suspend_msg(WMA_HANDLE handle)
 			WMA_TGT_SUSPEND_COMPLETE_TIMEOUT) !=
 			QDF_STATUS_SUCCESS) {
 		WMA_LOGE("Failed to get runtime suspend event");
-		goto failure;
+		goto msg_timed_out;
 	}
 
 	return QDF_STATUS_SUCCESS;
 
+msg_timed_out:
+	wma_post_runtime_resume_msg(wma);
 failure:
 	return QDF_STATUS_E_AGAIN;
 }

+ 5 - 0
core/wma/src/wma_main.c

@@ -1665,6 +1665,9 @@ QDF_STATUS wma_open(void *cds_context,
 	wma_handle->qdf_dev = qdf_dev;
 	wma_handle->max_scan = mac_params->max_scan;
 
+	wma_handle->wma_runtime_resume_lock =
+		qdf_runtime_lock_init("wma_runtime_resume");
+
 	/* initialize default target config */
 	wma_set_default_tgt_config(wma_handle);
 
@@ -2075,6 +2078,8 @@ err_wma_handle:
 #endif /* FEATURE_WLAN_EXTSCAN */
 		qdf_wake_lock_destroy(&wma_handle->wow_wake_lock);
 	}
+
+	qdf_runtime_lock_deinit(wma_handle->wma_runtime_resume_lock);
 	cds_free_context(cds_context, QDF_MODULE_ID_WMA, wma_handle);
 
 	WMA_LOGD("%s: Exit", __func__);