Browse Source

qcacld-3.0: Avoid race condition when vdev is deleted

qcacld-2.0 to qcacld-3.0 propagation

If SME posts message to WMI after vdev_detach happens,
there can be a race condition.
In this case VDEV_SET_PARAM will be called after VDEV_DELETE.
Fix this with introduction of new Boolean flag "is_vdev_valid" which
will be true after VDEV_CREATE is done. This flag will be false
when deletion of vdev happens.
WMI will do VDEV_SET_PARAM only if "is_vdev_valid" true.

Change-Id: Idffd0979bd9bdefa1225d2ea6a24180d81000f48
CRs-Fixed: 964146
Bhargav Shah 9 years ago
parent
commit
a89d3b4d80
3 changed files with 14 additions and 0 deletions
  1. 1 0
      core/wma/inc/wma.h
  2. 8 0
      core/wma/src/wma_dev_if.c
  3. 5 0
      core/wma/src/wma_main.c

+ 1 - 0
core/wma/inc/wma.h

@@ -991,6 +991,7 @@ struct wma_txrx_node {
 	uint8_t wep_default_key_idx;
 	tSirHostOffloadReq arp_offload_req;
 	tSirHostOffloadReq ns_offload_req;
+	bool is_vdev_valid;
 };
 
 #if defined(QCA_WIFI_FTM)

+ 8 - 0
core/wma/src/wma_dev_if.c

@@ -546,6 +546,8 @@ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle,
 	if (!generate_rsp) {
 		WMA_LOGE("Call txrx detach w/o callback for vdev %d", vdev_id);
 		ol_txrx_vdev_detach(iface->handle, NULL, NULL);
+		iface->handle = NULL;
+		wma_handle->interfaces[vdev_id].is_vdev_valid = false;
 		goto out;
 	}
 
@@ -573,6 +575,8 @@ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle,
 	}
 	WMA_LOGD("Call txrx detach with callback for vdev %d", vdev_id);
 	ol_txrx_vdev_detach(iface->handle, NULL, NULL);
+	iface->handle = NULL;
+	wma_handle->interfaces[vdev_id].is_vdev_valid = false;
 
 	/*
 	 * send the response immediately if WMI_SERVICE_SYNC_DELETE_CMDS
@@ -1525,6 +1529,7 @@ ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle,
 	tSirMacHTCapabilityInfo *phtCapInfo;
 	cds_msg_t sme_msg = { 0 };
 	struct vdev_create_params params = { 0 };
+	u_int8_t vdev_id;
 
 	if (NULL == mac) {
 		WMA_LOGE("%s: Failed to get mac", __func__);
@@ -1547,6 +1552,8 @@ ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle,
 		goto end;
 	}
 
+	vdev_id = self_sta_req->session_id;
+
 	txrx_vdev_type = wma_get_txrx_vdev_type(self_sta_req->type);
 
 	if (wlan_op_mode_unknown == txrx_vdev_type) {
@@ -1652,6 +1659,7 @@ ol_txrx_vdev_handle wma_vdev_attach(tp_wma_handle wma_handle,
 		}
 	}
 
+	wma_handle->interfaces[vdev_id].is_vdev_valid = true;
 	ret = wma_vdev_set_param(wma_handle->wmi_handle,
 				self_sta_req->session_id,
 				WMI_VDEV_PARAM_MCC_RTSCTS_PROTECTION_ENABLE,

+ 5 - 0
core/wma/src/wma_main.c

@@ -872,6 +872,11 @@ static void wma_process_cli_set_cmd(tp_wma_handle wma,
 
 	switch (privcmd->param_vp_dev) {
 	case VDEV_CMD:
+		if (!wma->interfaces[privcmd->param_vdev_id].is_vdev_valid) {
+			WMA_LOGE("%s Vdev id is not valid", __func__);
+			return ;
+		}
+
 		WMA_LOGD("vdev id %d pid %d pval %d", privcmd->param_vdev_id,
 			 privcmd->param_id, privcmd->param_value);
 		ret = wma_vdev_set_param(wma->wmi_handle,