From c45db899eb6ef40e9ccc9642872513dd6a48fd5a Mon Sep 17 00:00:00 2001 From: Houston Hoffman Date: Fri, 13 Nov 2015 19:59:25 -0800 Subject: [PATCH] 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 --- core/wma/inc/wma.h | 1 + core/wma/src/wma_features.c | 21 +++++++++++++++++++-- core/wma/src/wma_main.c | 5 +++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 364aeb47f084..bb3f24ea13c1 100644 --- a/core/wma/inc/wma.h +++ b/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; diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index a68cade641d8..07c85455c37b 100644 --- a/core/wma/src/wma_features.c +++ b/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; } diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c index d52b44637165..625ae4e83b41 100644 --- a/core/wma/src/wma_main.c +++ b/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__);