qcacld-3.0: Move from qdf event to linux completion for vdev destroy

Whenever there is a process waiting on a response from firmware it has the
option of using either a qdf_event or a linux completion event.
The primary difference between these is that if there is an SSR all
qdf_events are immediately completed whereas Linux completion events are
only completed by the normal flow of code.

With new upcoming changes SSR processing will take the normal path for
releasing all of its resources, and the qdf_session_close_event is used for
synchronization.
If we define this as a qdf_event, it will be completed when the SSR begins,
defeating its purpose.

Therefore change this to be a Linux completion event.

Change-Id: Ia6fe504e2a2d01f12c3d3446fffc2fc397566966
CRs-Fixed: 2586190
This commit is contained in:
Arun Kumar Khandavalli 2019-12-13 18:46:04 +05:30 committed by nshrivas
parent e7a73bf599
commit c988c53ea7
3 changed files with 19 additions and 24 deletions

View File

@ -1103,8 +1103,17 @@ struct hdd_adapter {
/* estimated link speed */
uint32_t estimated_linkspeed;
/* QDF event for session close */
qdf_event_t qdf_session_close_event;
/**
* vdev_destroy_event is moved from the qdf_event to linux event
* consciously, Lets take example when sap interface is waiting on the
* session_close event and then there is a SSR the wait event is
* completed the interface down is returned and the next command to the
* driver will hdd_hostapd_uinit-->vhdd_deinit_ap_mode-->
* hdd_hostapd_deinit_sap_session where in the sap_ctx would be freed.
* During the SSR if the same sap context is used it would result
* in null pointer de-reference.
*/
struct completion vdev_destroy_event;
/* QDF event for session open */
qdf_event_t qdf_session_open_event;

View File

@ -3514,13 +3514,7 @@ struct hdd_adapter *hdd_wlan_create_ap_dev(struct hdd_context *hdd_ctx,
return NULL;
}
qdf_status = qdf_event_create(
&adapter->qdf_session_close_event);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
hdd_err("failed to create session close QDF event!");
free_netdev(adapter->dev);
return NULL;
}
init_completion(&adapter->vdev_destroy_event);
SET_NETDEV_DEV(dev, hdd_ctx->parent_dev);
spin_lock_init(&adapter->pause_map_lock);

View File

@ -4287,9 +4287,7 @@ hdd_alloc_station_adapter(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr,
if (QDF_IS_STATUS_ERROR(qdf_status))
goto free_net_dev;
qdf_status = qdf_event_create(&adapter->qdf_session_close_event);
if (QDF_IS_STATUS_ERROR(qdf_status))
goto free_net_dev;
init_completion(&adapter->vdev_destroy_event);
adapter->offloads_configured = false;
adapter->is_link_up_service_needed = false;
@ -4408,7 +4406,7 @@ QDF_STATUS hdd_sme_close_session_callback(uint8_t vdev_id)
* valid, before signaling completion
*/
if (WLAN_HDD_ADAPTER_MAGIC == adapter->magic)
qdf_event_set(&adapter->qdf_session_close_event);
complete(&adapter->vdev_destroy_event);
return QDF_STATUS_SUCCESS;
}
@ -4451,6 +4449,7 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter)
struct hdd_context *hdd_ctx;
uint8_t vdev_id;
struct wlan_objmgr_vdev *vdev;
long rc;
vdev_id = adapter->vdev_id;
hdd_info("destroying vdev %d", vdev_id);
@ -4488,7 +4487,7 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter)
wlan_ser_vdev_queue_disable(adapter->vdev);
/* close sme session (destroy vdev in firmware via legacy API) */
qdf_event_reset(&adapter->qdf_session_close_event);
INIT_COMPLETION(adapter->vdev_destroy_event);
status = sme_vdev_delete(hdd_ctx->mac_handle, vdev);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("failed to delete vdev; status:%d", status);
@ -4496,11 +4495,9 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter)
}
/* block on a completion variable until sme session is closed */
status = qdf_wait_for_event_completion(
&adapter->qdf_session_close_event,
SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
if (QDF_IS_STATUS_ERROR(status)) {
rc = wait_for_completion_timeout(&adapter->vdev_destroy_event,
SME_CMD_VDEV_CREATE_DELETE_TIMEOUT);
if (rc) {
clear_bit(SME_SESSION_OPENED, &adapter->event_flags);
if (adapter->device_mode == QDF_NDI_MODE)
@ -4509,11 +4506,6 @@ int hdd_vdev_destroy(struct hdd_adapter *adapter)
if (status == QDF_STATUS_E_TIMEOUT) {
hdd_err("timed out waiting for sme vdev delete");
sme_cleanup_session(hdd_ctx->mac_handle, vdev_id);
} else if (adapter->qdf_session_close_event.force_set) {
hdd_info("SSR occurred during sme vdev delete");
} else {
hdd_err("failed to wait for sme vdev delete; status:%u",
status);
}
}