qcacmn: Fix hotspot starting failure
When softap is stopping, there are two threads accessing the "conc_connection_list". hostapd thread (__wlan_hdd_cfg80211_stop_ap) read and modify it by cds_decr_session_set_pcl. cds_mc_thread thread (cds_get_valid_chan_weights) read and modify it by cds_store_and_del_conn_info and cds_restore_deleted_conn_info. They are not protected,which causes two same station connection info saved to the "conc_connection_list". This fix is to acquire lock before read/modify the list. Change-Id: I5f1becef711363f659044c46e69fab1cd6d07d81 CRs-Fixed: 2038000
This commit is contained in:
parent
05328bb022
commit
0027e3f02b
@ -1207,6 +1207,13 @@ void policy_mgr_set_pcl_for_existing_combo(
|
||||
info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
|
||||
enum tQDF_ADAPTER_MODE pcl_mode;
|
||||
uint8_t num_cxn_del = 0;
|
||||
struct policy_mgr_psoc_priv_obj *pm_ctx;
|
||||
|
||||
pm_ctx = policy_mgr_get_context(psoc);
|
||||
if (!pm_ctx) {
|
||||
policy_mgr_err("Invalid Context");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case PM_STA_MODE:
|
||||
@ -1228,17 +1235,20 @@ void policy_mgr_set_pcl_for_existing_combo(
|
||||
policy_mgr_err("Invalid mode to set PCL");
|
||||
return;
|
||||
};
|
||||
|
||||
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
|
||||
if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) {
|
||||
/* 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);
|
||||
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);
|
||||
}
|
||||
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,20 +76,30 @@ QDF_STATUS policy_mgr_get_pcl_for_existing_conn(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t num_cxn_del = 0;
|
||||
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
struct policy_mgr_psoc_priv_obj *pm_ctx;
|
||||
|
||||
policy_mgr_debug("get pcl for existing conn:%d", mode);
|
||||
pm_ctx = policy_mgr_get_context(psoc);
|
||||
if (!pm_ctx) {
|
||||
policy_mgr_err("Invalid Context");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
|
||||
if (policy_mgr_mode_specific_connection_count(psoc, mode, NULL) > 0) {
|
||||
/* Check, store and temp delete the mode's parameter */
|
||||
policy_mgr_store_and_del_conn_info(psoc, mode,
|
||||
all_matching_cxn_to_del, info, &num_cxn_del);
|
||||
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
||||
/* Get the PCL */
|
||||
status = policy_mgr_get_pcl(psoc, mode, pcl_ch, len,
|
||||
pcl_weight, weight_len);
|
||||
policy_mgr_debug("Get 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);
|
||||
}
|
||||
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -1599,6 +1609,13 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
|
||||
struct policy_mgr_conc_connection_info
|
||||
info[MAX_NUMBER_OF_CONC_CONNECTIONS] = { {0} };
|
||||
uint8_t num_cxn_del = 0;
|
||||
struct policy_mgr_psoc_priv_obj *pm_ctx;
|
||||
|
||||
pm_ctx = policy_mgr_get_context(psoc);
|
||||
if (!pm_ctx) {
|
||||
policy_mgr_err("Invalid Context");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
if (!weight->pcl_list) {
|
||||
policy_mgr_err("Invalid pcl");
|
||||
@ -1617,7 +1634,7 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
|
||||
|
||||
qdf_mem_set(weight->weighed_valid_list, QDF_MAX_NUM_CHAN,
|
||||
WEIGHT_OF_DISALLOWED_CHANNELS);
|
||||
|
||||
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
|
||||
if (policy_mgr_mode_specific_connection_count(
|
||||
psoc, PM_STA_MODE, NULL) > 0) {
|
||||
/*
|
||||
@ -1628,6 +1645,7 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
|
||||
*/
|
||||
policy_mgr_store_and_del_conn_info(psoc, PM_STA_MODE, false,
|
||||
info, &num_cxn_del);
|
||||
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
||||
/*
|
||||
* There is a small window between releasing the above lock
|
||||
* and acquiring the same in policy_mgr_allow_concurrency,
|
||||
@ -1641,10 +1659,11 @@ QDF_STATUS policy_mgr_get_valid_chan_weights(struct wlan_objmgr_psoc *psoc,
|
||||
WEIGHT_OF_NON_PCL_CHANNELS;
|
||||
}
|
||||
}
|
||||
|
||||
qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock);
|
||||
/* Restore the connection info */
|
||||
policy_mgr_restore_deleted_conn_info(psoc, info, num_cxn_del);
|
||||
}
|
||||
qdf_mutex_release(&pm_ctx->qdf_conc_list_lock);
|
||||
|
||||
for (i = 0; i < weight->saved_num_chan; i++) {
|
||||
for (j = 0; j < weight->pcl_len; j++) {
|
||||
|
Loading…
Reference in New Issue
Block a user