qcacld-3.0: resolve race issue accessing pm_conc_connection_list
While function policy_mgr_set_pcl_for_existing_combo posts event SIR_HAL_PDEV_SET_PCL_TO_FW and before restores pm_conc_connection_list, the function policy_mgr_get_valid_chan_weights is invoking and accessing pm_conc_connection_list then race happens. To resolve the issue, restore the pm_conc_connection_list before calling SME function. CRs-Fixed: 2362839 Change-Id: I8b30dc5084c4aae4bcc4b3b350d19c8be89338a9
这个提交包含在:
@@ -790,14 +790,15 @@ void policy_mgr_restore_deleted_conn_info(struct wlan_objmgr_psoc *psoc,
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
|
||||
conn_index = policy_mgr_get_connection_count(psoc);
|
||||
if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
|
||||
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
||||
policy_mgr_err("Failed to restore the deleted information %d/%d",
|
||||
conn_index, MAX_NUMBER_OF_CONC_CONNECTIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
|
||||
qdf_mem_copy(&pm_conc_connection_list[conn_index], info,
|
||||
num_cxn_del * sizeof(*info));
|
||||
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
||||
@@ -1245,31 +1246,14 @@ void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc)
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* policy_mgr_pdev_set_pcl() - Sets PCL to FW
|
||||
* @mode: adapter mode
|
||||
*
|
||||
* Fetches the PCL and sends the PCL to SME
|
||||
* module which in turn will send the WMI
|
||||
* command WMI_PDEV_SET_PCL_CMDID to the fw
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc,
|
||||
enum QDF_OPMODE mode)
|
||||
QDF_STATUS policy_mgr_pdev_get_pcl(struct wlan_objmgr_psoc *psoc,
|
||||
enum QDF_OPMODE mode,
|
||||
struct policy_mgr_pcl_list *pcl)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
enum policy_mgr_con_mode con_mode;
|
||||
struct policy_mgr_pcl_list pcl;
|
||||
struct policy_mgr_psoc_priv_obj *pm_ctx;
|
||||
|
||||
pm_ctx = policy_mgr_get_context(psoc);
|
||||
if (!pm_ctx) {
|
||||
policy_mgr_err("Invalid Context");
|
||||
return;
|
||||
}
|
||||
|
||||
pcl.pcl_len = 0;
|
||||
pcl->pcl_len = 0;
|
||||
|
||||
switch (mode) {
|
||||
case QDF_STA_MODE:
|
||||
@@ -1289,24 +1273,18 @@ void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc,
|
||||
break;
|
||||
default:
|
||||
policy_mgr_err("Unable to set PCL to FW: %d", mode);
|
||||
return;
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
policy_mgr_debug("get pcl to set it to the FW");
|
||||
|
||||
status = policy_mgr_get_pcl(psoc, con_mode,
|
||||
pcl.pcl_list, &pcl.pcl_len,
|
||||
pcl.weight_list, QDF_ARRAY_SIZE(pcl.weight_list));
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
policy_mgr_err("Unable to set PCL to FW, Get PCL failed");
|
||||
return;
|
||||
}
|
||||
|
||||
status = pm_ctx->sme_cbacks.sme_pdev_set_pcl(&pcl);
|
||||
pcl->pcl_list, &pcl->pcl_len,
|
||||
pcl->weight_list, QDF_ARRAY_SIZE(pcl->weight_list));
|
||||
if (status != QDF_STATUS_SUCCESS)
|
||||
policy_mgr_err("Send soc set PCL to SME failed");
|
||||
else
|
||||
policy_mgr_debug("Set PCL to FW for mode:%d", mode);
|
||||
policy_mgr_err("Unable to set PCL to FW, Get PCL failed");
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1320,11 +1298,13 @@ void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc,
|
||||
void policy_mgr_set_pcl_for_existing_combo(
|
||||
struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct policy_mgr_conc_connection_info
|
||||
info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
|
||||
enum QDF_OPMODE pcl_mode;
|
||||
uint8_t num_cxn_del = 0;
|
||||
struct policy_mgr_psoc_priv_obj *pm_ctx;
|
||||
struct policy_mgr_pcl_list pcl;
|
||||
|
||||
pm_ctx = policy_mgr_get_context(psoc);
|
||||
if (!pm_ctx) {
|
||||
@@ -1337,18 +1317,24 @@ void policy_mgr_set_pcl_for_existing_combo(
|
||||
return;
|
||||
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
|
||||
if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) {
|
||||
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
||||
/* Check, store and temp delete the mode's parameter */
|
||||
policy_mgr_store_and_del_conn_info(psoc, mode, false,
|
||||
info, &num_cxn_del);
|
||||
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
||||
/* Set the PCL to the FW since connection got updated */
|
||||
policy_mgr_pdev_set_pcl(psoc, pcl_mode);
|
||||
status = policy_mgr_pdev_get_pcl(psoc, pcl_mode, &pcl);
|
||||
policy_mgr_debug("Set PCL to FW for mode:%d", mode);
|
||||
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
|
||||
/* Restore the connection info */
|
||||
policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
|
||||
|
||||
if (QDF_IS_STATUS_SUCCESS(status)) {
|
||||
status = pm_ctx->sme_cbacks.sme_pdev_set_pcl(&pcl);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
policy_mgr_err("Send set PCL to SME failed");
|
||||
}
|
||||
} else {
|
||||
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
||||
}
|
||||
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
||||
}
|
||||
|
||||
static uint32_t pm_get_vdev_id_of_first_conn_idx(struct wlan_objmgr_psoc *psoc)
|
||||
|
@@ -468,14 +468,18 @@ void policy_mgr_pdev_set_hw_mode_cb(uint32_t status,
|
||||
void policy_mgr_dump_current_concurrency(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* policy_mgr_pdev_set_pcl() - SET PCL channel list and send to firmware
|
||||
* policy_mgr_pdev_get_pcl() - GET PCL channel list
|
||||
* @psoc: PSOC object information
|
||||
* @mode: Adapter mode
|
||||
* @pcl: the pointer of pcl list
|
||||
*
|
||||
* Return: None
|
||||
* Fetches the PCL.
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
void policy_mgr_pdev_set_pcl(struct wlan_objmgr_psoc *psoc,
|
||||
enum QDF_OPMODE mode);
|
||||
QDF_STATUS policy_mgr_pdev_get_pcl(struct wlan_objmgr_psoc *psoc,
|
||||
enum QDF_OPMODE mode,
|
||||
struct policy_mgr_pcl_list *pcl);
|
||||
void pm_dbs_opportunistic_timer_handler(void *data);
|
||||
enum policy_mgr_con_mode policy_mgr_get_mode(uint8_t type,
|
||||
uint8_t subtype);
|
||||
|
在新工单中引用
屏蔽一个用户