qcacld-3.0: Acquire sap context before access

Fix potential race condition issue when the sap_context
of adapter is null and it is accessed in work queue -
 __policy_mgr_check_sta_ap_concurrent_ch_intf.
To acquire/release the "sap_context" by get/put API.

Change-Id: I91dacc6d45c377840f7d30f2f9ff902f53ccd8e8
CRs-Fixed: 2592524
这个提交包含在:
Liangwei Dong
2019-12-24 15:36:36 +08:00
提交者 nshrivas
父节点 5c414e821f
当前提交 825d2fc8f3
修改 3 个文件,包含 26 行新增12 行删除

查看文件

@@ -1979,6 +1979,11 @@ void policy_mgr_check_concurrent_intf_and_restart_sap(
policy_mgr_err("Invalid sta_ap_intf_check_work_info"); policy_mgr_err("Invalid sta_ap_intf_check_work_info");
return; return;
} }
if (!policy_mgr_is_sap_go_existed(psoc)) {
policy_mgr_debug(
"No action taken at check_concurrent_intf_and_restart_sap");
return;
}
/* /*
* If STA+SAP sessions are on DFS channel and STA+SAP SCC is * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
* enabled on DFS channel then move the SAP out of DFS channel * enabled on DFS channel then move the SAP out of DFS channel
@@ -2012,13 +2017,6 @@ void policy_mgr_check_concurrent_intf_and_restart_sap(
policy_mgr_get_mcc_to_scc_switch_mode(psoc); policy_mgr_get_mcc_to_scc_switch_mode(psoc);
policy_mgr_info("MCC to SCC switch: %d chan: %d", policy_mgr_info("MCC to SCC switch: %d chan: %d",
mcc_to_scc_switch, op_ch_freq_list[0]); mcc_to_scc_switch, op_ch_freq_list[0]);
if (!policy_mgr_is_sap_go_existed(psoc)) {
policy_mgr_debug(
"No action taken at check_concurrent_intf_and_restart_sap");
return;
}
sap_restart: sap_restart:
/* /*
* If sta_sap_scc_on_dfs_chan is true then standalone SAP is not * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not

查看文件

@@ -3092,6 +3092,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev( struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev(
psoc, vdev_id); psoc, vdev_id);
uint32_t sap_ch_freq, intf_ch_freq; uint32_t sap_ch_freq, intf_ch_freq;
struct sap_context *sap_context;
if (!ap_adapter) { if (!ap_adapter) {
hdd_err("ap_adapter is NULL"); hdd_err("ap_adapter is NULL");
@@ -3115,12 +3116,20 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
} }
hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter); hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
mac_handle = hdd_ctx->mac_handle; mac_handle = hdd_ctx->mac_handle;
if (!mac_handle) { if (!mac_handle) {
hdd_err("mac_handle is NULL"); hdd_err("mac_handle is NULL");
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
sap_context = hdd_ap_ctx->sap_context;
if (!sap_context) {
hdd_err("sap_context is null");
return QDF_STATUS_E_FAILURE;
}
if (QDF_IS_STATUS_ERROR(wlansap_context_get(sap_context))) {
hdd_err("sap_context is invalid");
return QDF_STATUS_E_FAILURE;
}
/* /*
* If STA+SAP sessions are on DFS channel and STA+SAP SCC is * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
@@ -3142,7 +3151,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
* supported, return from here if DBS is not supported. * supported, return from here if DBS is not supported.
* Need to take care of 3 port cases with 2 STA iface in future. * Need to take care of 3 port cases with 2 STA iface in future.
*/ */
intf_ch_freq = wlansap_check_cc_intf(hdd_ap_ctx->sap_context); intf_ch_freq = wlansap_check_cc_intf(sap_context);
policy_mgr_get_chan_by_session_id(psoc, vdev_id, &sap_ch_freq); policy_mgr_get_chan_by_session_id(psoc, vdev_id, &sap_ch_freq);
hdd_info("sap_vdev %d intf_ch: %d, orig freq: %d", hdd_info("sap_vdev %d intf_ch: %d, orig freq: %d",
vdev_id, intf_ch_freq, sap_ch_freq); vdev_id, intf_ch_freq, sap_ch_freq);
@@ -3151,6 +3160,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
if (QDF_IS_STATUS_ERROR( if (QDF_IS_STATUS_ERROR(
policy_mgr_valid_sap_conc_channel_check( policy_mgr_valid_sap_conc_channel_check(
hdd_ctx->psoc, &intf_ch_freq, sap_ch_freq, vdev_id))) { hdd_ctx->psoc, &intf_ch_freq, sap_ch_freq, vdev_id))) {
wlansap_context_put(sap_context);
hdd_debug("can't move sap to chan(freq): %u", hdd_debug("can't move sap to chan(freq): %u",
intf_ch_freq); intf_ch_freq);
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
@@ -3159,13 +3169,14 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
sap_restart: sap_restart:
if (!intf_ch_freq) { if (!intf_ch_freq) {
intf_ch_freq = wlansap_get_chan_band_restrict(hdd_ap_ctx->sap_context); intf_ch_freq = wlansap_get_chan_band_restrict(sap_context);
if (intf_ch_freq == sap_ch_freq) if (intf_ch_freq == sap_ch_freq)
intf_ch_freq = 0; intf_ch_freq = 0;
} else if (hdd_ap_ctx->sap_context) } else
hdd_ap_ctx->sap_context->csa_reason = sap_context->csa_reason =
CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL; CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL;
if (!intf_ch_freq) { if (!intf_ch_freq) {
wlansap_context_put(sap_context);
hdd_debug("interface channel is 0"); hdd_debug("interface channel is 0");
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
} }
@@ -3183,6 +3194,7 @@ sap_restart:
hdd_info("SAP channel change with CSA/ECSA"); hdd_info("SAP channel change with CSA/ECSA");
hdd_sap_restart_chan_switch_cb(psoc, vdev_id, *ch_freq, hdd_sap_restart_chan_switch_cb(psoc, vdev_id, *ch_freq,
ch_params.ch_width, false); ch_params.ch_width, false);
wlansap_context_put(sap_context);
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }

查看文件

@@ -3164,6 +3164,10 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx)
enum reg_wifi_band sap_band; enum reg_wifi_band sap_band;
enum band_info band; enum band_info band;
if (!sap_ctx) {
sap_err("sap_ctx NULL parameter");
return 0;
}
if (cds_is_driver_recovering()) if (cds_is_driver_recovering())
return 0; return 0;