Browse Source

qcacld-3.0: Code refractor for ML debug id

Currently, in some API such as
"wlan_cfg80211_tdls_add_peer_mlo", when driver gets vdev, it is
MLO vdev, so it uses WLAN_MLO_MGR_ID ID, but when it tries to put
the vdev, since disconnection happens and mlo flag is cleared,
so it uses WLAN_OSIF_TDLS_ID ID which is non-ML vdev.
This causes release of vdev reference from different id for which
it never takes reference and result in crash.

To fix this, use same debug id throughout function. For that,
generalize the get_ml_vdev API by passing the debug id as
argument to the function.

Change-Id: I903185ec9b64cc67cc2e0c595ba88b7b0ca8ded2
CRs-Fixed: 3603012
Rahul Gusain 1 year ago
parent
commit
59b19dff23

+ 3 - 2
components/mlme/dispatcher/src/wlan_mlme_ucfg_api.c

@@ -435,7 +435,8 @@ ucfg_mlme_send_ch_width_update_with_notify(struct wlan_objmgr_psoc *psoc,
 	}
 
 	if (wlan_vdev_mlme_is_mlo_vdev(vdev) && link_id != 0xFF) {
-		link_vdev = mlo_get_vdev_by_link_id(vdev, link_id);
+		link_vdev = mlo_get_vdev_by_link_id(vdev, link_id,
+						    WLAN_MLME_OBJMGR_ID);
 		if (!link_vdev) {
 			mlme_legacy_debug("vdev is null for the link id:%u",
 					  link_id);
@@ -452,7 +453,7 @@ ucfg_mlme_send_ch_width_update_with_notify(struct wlan_objmgr_psoc *psoc,
 							    link_vdev_id,
 							    ch_width);
 	if (is_mlo_link)
-		mlo_release_vdev_ref(link_vdev);
+		wlan_objmgr_vdev_release_ref(link_vdev, WLAN_MLME_OBJMGR_ID);
 
 release:
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLME_OBJMGR_ID);

+ 8 - 6
components/umac/mlme/mlo_mgr/src/wlan_epcs_api.c

@@ -338,7 +338,8 @@ static QDF_STATUS epcs_handle_rx_req(struct wlan_objmgr_vdev *vdev,
 	edca_info = &epcs_req.pa_info;
 	for (i = 0; i < edca_info->num_links; i++) {
 		link = &edca_info->link_info[i];
-		link_vdev = mlo_get_vdev_by_link_id(vdev, link->link_id);
+		link_vdev = mlo_get_vdev_by_link_id(vdev, link->link_id,
+						    WLAN_MLO_MGR_ID);
 		if (!link_vdev)
 			continue;
 
@@ -353,7 +354,7 @@ static QDF_STATUS epcs_handle_rx_req(struct wlan_objmgr_vdev *vdev,
 		if (link->muedca_ie_present)
 			epcs_update_mu_edca_param(link_vdev, &link->muedca);
 
-		mlo_release_vdev_ref(link_vdev);
+		wlan_objmgr_vdev_release_ref(link_vdev, WLAN_MLO_MGR_ID);
 	}
 
 	args.category = ACTION_CATEGORY_PROTECTED_EHT;
@@ -389,11 +390,11 @@ static QDF_STATUS epcs_handle_rx_resp(struct wlan_objmgr_vdev *vdev,
 	QDF_STATUS status;
 
 	if (!vdev || !peer)
-		return QDF_STATUS_E_INVAL;
+		return QDF_STATUS_E_NULL_VALUE;
 
 	ml_peer = peer->mlo_peer_ctx;
 	if (!ml_peer)
-		return QDF_STATUS_E_FAILURE;
+		return QDF_STATUS_E_NULL_VALUE;
 
 	epcs_info = &ml_peer->epcs_info;
 	if (epcs_info->state == EPCS_ENABLE) {
@@ -421,7 +422,8 @@ static QDF_STATUS epcs_handle_rx_resp(struct wlan_objmgr_vdev *vdev,
 	edca_info = &epcs_rsp.pa_info;
 	for (i = 0; i < edca_info->num_links; i++) {
 		link = &edca_info->link_info[i];
-		link_vdev = mlo_get_vdev_by_link_id(vdev, link->link_id);
+		link_vdev = mlo_get_vdev_by_link_id(vdev, link->link_id,
+						    WLAN_MLO_MGR_ID);
 		if (!link_vdev)
 			continue;
 
@@ -436,7 +438,7 @@ static QDF_STATUS epcs_handle_rx_resp(struct wlan_objmgr_vdev *vdev,
 		if (link->muedca_ie_present)
 			epcs_update_mu_edca_param(link_vdev, &link->muedca);
 
-		mlo_release_vdev_ref(link_vdev);
+		wlan_objmgr_vdev_release_ref(link_vdev, WLAN_MLO_MGR_ID);
 	}
 
 	epcs_info->state = EPCS_ENABLE;

+ 23 - 19
core/hdd/src/wlan_hdd_cfg80211.c

@@ -12268,6 +12268,7 @@ static int hdd_get_mlo_max_band_info(struct wlan_hdd_link_info *link_info,
 	struct wlan_objmgr_vdev *vdev, *link_vdev;
 	struct wlan_channel *bss_chan;
 	uint8_t nl80211_chwidth;
+	int8_t ret = 0;
 
 	chwidth = wma_cli_get_command(link_info->vdev_id,
 				      wmi_vdev_param_chwidth, VDEV_CMD);
@@ -12283,47 +12284,50 @@ static int hdd_get_mlo_max_band_info(struct wlan_hdd_link_info *link_info,
 	if (wlan_vdev_mlme_is_mlo_vdev(vdev)) {
 		mlo_bd_info = nla_nest_start(skb, CONFIG_MLO_LINKS);
 		for (link_id = 0; link_id < WLAN_MAX_LINK_ID; link_id++) {
-			link_vdev = mlo_get_vdev_by_link_id(vdev, link_id);
+			link_vdev = mlo_get_vdev_by_link_id(vdev, link_id,
+							    WLAN_OSIF_ID);
 			if (!link_vdev)
 				continue;
 
 			mlo_bd = nla_nest_start(skb, i);
 			if (!mlo_bd) {
-				hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
-				mlo_release_vdev_ref(link_vdev);
 				hdd_err("nla_nest_start fail");
-				return -EINVAL;
+				ret = -EINVAL;
+				goto end;
 			}
 			bss_chan = wlan_vdev_mlme_get_bss_chan(link_vdev);
 			if (!bss_chan) {
-				hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
-				mlo_release_vdev_ref(link_vdev);
 				hdd_err("fail to get bss_chan info");
-				return QDF_STATUS_E_FAILURE;
+				ret = -EINVAL;
+				goto end;
 			}
 			if (nla_put_u8(skb, CONFIG_MLO_LINK_ID, link_id)) {
-				hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
-				mlo_release_vdev_ref(link_vdev);
 				hdd_err("nla_put failure");
-				return -EINVAL;
+				ret = -EINVAL;
+				goto end;
 			}
 
 			nl80211_chwidth = hdd_phy_chwidth_to_nl80211_chwidth(bss_chan->ch_width);
 			if (nla_put_u8(skb, CONFIG_CHANNEL_WIDTH,
 				       nl80211_chwidth)) {
-				hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
-				mlo_release_vdev_ref(link_vdev);
 				hdd_err("nla_put failure");
-				return -EINVAL;
+				ret = -EINVAL;
+				goto end;
 			}
 			nla_nest_end(skb, mlo_bd);
 			i++;
-			mlo_release_vdev_ref(link_vdev);
+			hdd_objmgr_put_vdev_by_user(link_vdev, WLAN_OSIF_ID);
 		}
 		nla_nest_end(skb, mlo_bd_info);
 	}
+
+end:
 	hdd_objmgr_put_vdev_by_user(vdev, WLAN_OSIF_ID);
-	return 0;
+
+	if (ret)
+		hdd_objmgr_put_vdev_by_user(link_vdev, WLAN_OSIF_ID);
+
+	return ret;
 }
 
 /**
@@ -22750,7 +22754,7 @@ struct wlan_objmgr_vdev *wlan_key_get_link_vdev(struct hdd_adapter *adapter,
 	if (!wlan_vdev_mlme_is_mlo_vdev(vdev))
 		return vdev;
 
-	link_vdev = mlo_get_vdev_by_link_id(vdev, link_id);
+	link_vdev = mlo_get_vdev_by_link_id(vdev, link_id, id);
 	hdd_objmgr_put_vdev_by_user(vdev, id);
 
 	return link_vdev;
@@ -22764,7 +22768,7 @@ void wlan_key_put_link_vdev(struct wlan_objmgr_vdev *link_vdev,
 		return;
 	}
 
-	mlo_release_vdev_ref(link_vdev);
+	wlan_objmgr_vdev_release_ref(link_vdev, id);
 }
 #else
 struct wlan_objmgr_vdev *wlan_key_get_link_vdev(struct hdd_adapter *adapter,
@@ -23156,14 +23160,14 @@ static int wlan_hdd_add_key_vdev(mac_handle_t mac_handle,
 		} else if (wlan_vdev_mlme_is_mlo_link_vdev(vdev) &&
 			   adapter->device_mode == QDF_STA_MODE) {
 			status = wlan_objmgr_vdev_try_get_ref(vdev,
-							      WLAN_MLO_MGR_ID);
+							      WLAN_OSIF_ID);
 			if (QDF_IS_STATUS_ERROR(status)) {
 				hdd_err("Failed to get vdev ref");
 				return qdf_status_to_os_return(status);
 			}
 			status = wlan_hdd_mlo_copy_partner_addr_from_mlie(
 							vdev, &mac_address);
-			mlo_release_vdev_ref(vdev);
+			wlan_objmgr_vdev_release_ref(vdev, WLAN_OSIF_ID);
 			if (QDF_IS_STATUS_ERROR(status)) {
 				hdd_err("Failed to get peer address from ML IEs");
 				return qdf_status_to_os_return(status);

+ 9 - 17
core/mac/src/pe/lim/lim_api.c

@@ -4492,7 +4492,8 @@ lim_process_cu_for_probe_rsp(struct mac_context *mac_ctx,
 
 	for (i = 0; i < partner_info.num_partner_links; i++) {
 		link_id = partner_info.partner_link_info[i].link_id;
-		partner_vdev = mlo_get_vdev_by_link_id(vdev, link_id);
+		partner_vdev = mlo_get_vdev_by_link_id(vdev, link_id,
+						       WLAN_LEGACY_MAC_ID);
 		if (!partner_vdev) {
 			pe_debug("No partner vdev for link id %d", link_id);
 			continue;
@@ -4501,26 +4502,19 @@ lim_process_cu_for_probe_rsp(struct mac_context *mac_ctx,
 		status = lim_cu_info_from_rnr_per_link_id(rnr, link_id,
 							  &bpcc, &aui);
 		if (QDF_IS_STATUS_ERROR(status)) {
-			wlan_objmgr_vdev_release_ref(partner_vdev,
-						     WLAN_MLO_MGR_ID);
 			pe_debug("no cu info in rnr for link id %d", link_id);
-			continue;
+			goto ref_rel;
 		}
 
 		cu_flag = lim_check_cu_happens(partner_vdev, bpcc);
-		if (!cu_flag) {
-			wlan_objmgr_vdev_release_ref(partner_vdev,
-						     WLAN_MLO_MGR_ID);
-			continue;
-		}
+		if (!cu_flag)
+			goto ref_rel;
 
 		vdev_id = wlan_vdev_get_id(partner_vdev);
 		session = pe_find_session_by_vdev_id(mac_ctx, vdev_id);
 		if (!session) {
-			wlan_objmgr_vdev_release_ref(partner_vdev,
-						     WLAN_MLO_MGR_ID);
 			pe_debug("session is null for vdev id %d", vdev_id);
-			continue;
+			goto ref_rel;
 		}
 
 		qdf_mem_copy(&sta_link_addr, session->self_mac_addr,
@@ -4540,17 +4534,15 @@ lim_process_cu_for_probe_rsp(struct mac_context *mac_ctx,
 		if (QDF_IS_STATUS_ERROR(status)) {
 			pe_err("MLO: Link probe response generation failed %d",
 			       status);
-			wlan_objmgr_vdev_release_ref(partner_vdev,
-						     WLAN_MLO_MGR_ID);
-			continue;
+			goto ref_rel;
 		}
 
 		lim_process_gen_probe_rsp_frame(mac_ctx, session,
 						link_probe_rsp.ptr,
 						link_probe_rsp.len);
 
-		wlan_objmgr_vdev_release_ref(partner_vdev,
-					     WLAN_MLO_MGR_ID);
+ref_rel:
+		wlan_objmgr_vdev_release_ref(partner_vdev, WLAN_LEGACY_MAC_ID);
 	}
 
 	qdf_mem_free(link_probe_rsp.ptr);

+ 4 - 3
core/mac/src/pe/lim/lim_mlo.c

@@ -191,7 +191,7 @@ QDF_STATUS lim_partner_link_info_change(struct wlan_objmgr_vdev *vdev)
 
 void lim_mlo_release_vdev_ref(struct wlan_objmgr_vdev *vdev)
 {
-	mlo_release_vdev_ref(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_MLO_MGR_ID);
 }
 
 struct pe_session *pe_find_partner_session_by_link_id(
@@ -212,7 +212,8 @@ struct pe_session *pe_find_partner_session_by_link_id(
 		return NULL;
 	}
 
-	vdev = mlo_get_vdev_by_link_id(session->vdev, link_id);
+	vdev = mlo_get_vdev_by_link_id(session->vdev, link_id,
+				       WLAN_LEGACY_MAC_ID);
 
 	if (!vdev) {
 		pe_err("vdev is null");
@@ -223,7 +224,7 @@ struct pe_session *pe_find_partner_session_by_link_id(
 			mac, vdev->vdev_objmgr.vdev_id);
 
 	if (!partner_session)
-		lim_mlo_release_vdev_ref(vdev);
+		wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
 
 	return partner_session;
 }