Browse Source

qcacmn: 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: I5800d207fdd17692297e71a0a9cdbcb86a4c5650
CRs-Fixed: 3608817
Rahul Gusain 1 year ago
parent
commit
f0fc4d0daf

+ 14 - 10
os_if/linux/mlme/src/osif_cm_connect_rsp.c

@@ -471,10 +471,12 @@ osif_get_chan_bss_from_kernel(struct wlan_objmgr_vdev *vdev,
 
 #if defined(CFG80211_SINGLE_NETDEV_MULTI_LINK_SUPPORT) && defined(WLAN_FEATURE_11BE_MLO)
 #ifndef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
-static struct wlan_objmgr_vdev *osif_get_partner_vdev(struct wlan_objmgr_vdev *vdev,
-						      struct mlo_link_info rsp_partner_info)
+static struct wlan_objmgr_vdev *osif_get_partner_vdev(
+					struct wlan_objmgr_vdev *vdev,
+					struct mlo_link_info rsp_partner_info,
+					wlan_objmgr_ref_dbgid id)
 {
-	return mlo_get_vdev_by_link_id(vdev, rsp_partner_info.link_id);
+	return mlo_get_vdev_by_link_id(vdev, rsp_partner_info.link_id, id);
 }
 #endif
 
@@ -593,19 +595,20 @@ osif_free_ml_link_params(struct cfg80211_connect_resp_params *conn_rsp_params)
 #ifdef WLAN_FEATURE_11BE_MLO_ADV_FEATURE
 static struct wlan_objmgr_vdev *osif_get_partner_vdev(
 					struct wlan_objmgr_vdev *vdev,
-					struct mlo_link_info rsp_partner_info)
+					struct mlo_link_info rsp_partner_info,
+					wlan_objmgr_ref_dbgid id)
 {
 	return wlan_objmgr_get_vdev_by_id_from_pdev(
 						vdev->vdev_objmgr.wlan_pdev,
-						rsp_partner_info.vdev_id,
-						WLAN_MLO_MGR_ID);
+						rsp_partner_info.vdev_id, id);
 }
 #else
 static struct wlan_objmgr_vdev *osif_get_partner_vdev(
 					struct wlan_objmgr_vdev *vdev,
-					struct mlo_link_info rsp_partner_info)
+					struct mlo_link_info rsp_partner_info,
+					wlan_objmgr_ref_dbgid id)
 {
-	return mlo_get_vdev_by_link_id(vdev, rsp_partner_info.link_id);
+	return mlo_get_vdev_by_link_id(vdev, rsp_partner_info.link_id, id);
 }
 #endif
 static void osif_fill_connect_resp_mlo_params(
@@ -661,12 +664,13 @@ static void osif_fill_connect_resp_mlo_params(
 				break;
 
 			ml_vdev = osif_get_partner_vdev(vdev,
-							rsp_partner_info[i]);
+							rsp_partner_info[i],
+							WLAN_OSIF_CM_ID);
 
 			if (ml_vdev) {
 				osif_priv = wlan_vdev_get_ospriv(ml_vdev);
 				wlan_objmgr_vdev_release_ref(ml_vdev,
-							     WLAN_MLO_MGR_ID);
+							     WLAN_OSIF_CM_ID);
 			} else {
 				osif_err("Partner vdev not found with vdev_id:%d",
 					 rsp_partner_info[i].vdev_id);

+ 2 - 4
umac/mlo_mgr/inc/wlan_mlo_mgr_cmn.h

@@ -108,15 +108,13 @@ void is_mlo_all_links_up(struct wlan_mlo_dev_context *ml_dev);
  * mlo_get_vdev_by_link_id() - get vdev by link id
  * @vdev: vdev pointer
  * @link_id: link id
- *
- * Caller should make sure to release the reference of thus obtained vdev
- * by calling mlo_release_vdev_ref() after usage of vdev.
+ * @id: debug id
  *
  * Return: vdev object pointer to link id
  */
 struct wlan_objmgr_vdev *mlo_get_vdev_by_link_id(
 			struct wlan_objmgr_vdev *vdev,
-			uint8_t link_id);
+			uint8_t link_id, wlan_objmgr_ref_dbgid id);
 
 /**
  * mlo_release_vdev_ref() - release vdev reference

+ 4 - 5
umac/mlo_mgr/src/wlan_mlo_mgr_cmn.c

@@ -41,9 +41,9 @@ void is_mlo_all_links_up(struct wlan_mlo_dev_context *mldev)
 /* STA: Loop through all the associated vdev status. */
 }
 
-struct wlan_objmgr_vdev *mlo_get_vdev_by_link_id(
-			struct wlan_objmgr_vdev *vdev,
-			uint8_t link_id)
+struct wlan_objmgr_vdev *mlo_get_vdev_by_link_id(struct wlan_objmgr_vdev *vdev,
+						 uint8_t link_id,
+						 wlan_objmgr_ref_dbgid id)
 {
 	struct wlan_mlo_dev_context *dev_ctx;
 	int i;
@@ -64,8 +64,7 @@ struct wlan_objmgr_vdev *mlo_get_vdev_by_link_id(
 		    link_id) {
 			if (wlan_objmgr_vdev_try_get_ref(
 						dev_ctx->wlan_vdev_list[i],
-						WLAN_MLO_MGR_ID) ==
-							QDF_STATUS_SUCCESS)
+						id) == QDF_STATUS_SUCCESS)
 				partner_vdev = dev_ctx->wlan_vdev_list[i];
 
 			break;

+ 2 - 1
umac/mlo_mgr/src/wlan_mlo_mgr_peer.c

@@ -1039,7 +1039,8 @@ static QDF_STATUS mlo_dev_get_link_vdevs(
 	mlo_debug("num_partner_links %d", ml_info->num_partner_links);
 	for (i = 0; i < ml_info->num_partner_links; i++) {
 		link_id = ml_info->partner_link_info[i].link_id;
-		vdev_link = mlo_get_vdev_by_link_id(vdev, link_id);
+		vdev_link = mlo_get_vdev_by_link_id(vdev, link_id,
+						    WLAN_MLO_MGR_ID);
 		if (vdev_link) {
 			link_vdevs[i] = vdev_link;
 		} else {

+ 17 - 18
umac/mlo_mgr/src/wlan_mlo_mgr_primary_umac.c

@@ -1237,7 +1237,8 @@ wlan_mlo_get_new_ptqm_id(struct wlan_objmgr_vdev *curr_vdev,
 
 	if (new_primary_link_id != WLAN_LINK_ID_INVALID) {
 		link_vdev = mlo_get_vdev_by_link_id(curr_vdev,
-						    new_primary_link_id);
+						    new_primary_link_id,
+						    WLAN_MLO_MGR_ID);
 		if (!link_vdev) {
 			mlo_err("links vdev not found for link id %d",
 				new_primary_link_id);
@@ -1617,16 +1618,16 @@ QDF_STATUS wlan_mlo_set_ptqm_migration(struct wlan_objmgr_vdev *vdev,
 
 	if (!vdev) {
 		mlo_err("Vdev is NULL");
-		return QDF_STATUS_E_INVAL;
+		return QDF_STATUS_E_NULL_VALUE;
 	}
 
 	if (link_migration == false && !ml_peer) {
 		mlo_err("ML peer is NULL");
-		return QDF_STATUS_E_INVAL;
+		return QDF_STATUS_E_NULL_VALUE;
 	}
 
 	if (link_migration) {
-		mlo_err("Trigger migration for full link");
+		mlo_info("Trigger migration for full link");
 		// trigger full link migration
 		status = wlan_mlo_trigger_link_ptqm_migration(vdev);
 		if (QDF_IS_STATUS_ERROR(status))
@@ -1635,27 +1636,28 @@ QDF_STATUS wlan_mlo_set_ptqm_migration(struct wlan_objmgr_vdev *vdev,
 	}
 
 	if (ml_peer->link_peer_cnt == 1) {
-		mlo_err("peer " QDF_MAC_ADDR_FMT " is SLO",
-			QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes));
-		return QDF_STATUS_E_INVAL;
+		mlo_info("peer " QDF_MAC_ADDR_FMT " is SLO",
+			 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes));
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	if (ml_peer->primary_umac_migration_in_progress) {
-		mlo_err("peer " QDF_MAC_ADDR_FMT " primary umac migration already in progress",
-			QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes));
-		return QDF_STATUS_E_INVAL;
+		mlo_info("peer " QDF_MAC_ADDR_FMT " primary umac migration already in progress",
+			 QDF_MAC_ADDR_REF(ml_peer->peer_mld_addr.bytes));
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	current_primary_link_id = wlan_mlo_peer_get_primary_peer_link_id_by_ml_peer(ml_peer);
 	if (current_primary_link_id == WLAN_LINK_ID_INVALID) {
 		mlo_err("Current primary link id is invalid");
-		return QDF_STATUS_E_INVAL;
+		return QDF_STATUS_E_FAILURE;
 	}
 
-	curr_vdev = mlo_get_vdev_by_link_id(vdev, current_primary_link_id);
+	curr_vdev = mlo_get_vdev_by_link_id(vdev, current_primary_link_id,
+					    WLAN_MLO_MGR_ID);
 	if (!curr_vdev) {
 		mlo_err("Unable to get current primary vdev");
-		return QDF_STATUS_E_INVAL;
+		return QDF_STATUS_E_NULL_VALUE;
 	}
 
 	status = wlan_mlo_get_new_ptqm_id(curr_vdev, ml_peer,
@@ -1671,6 +1673,7 @@ QDF_STATUS wlan_mlo_set_ptqm_migration(struct wlan_objmgr_vdev *vdev,
 				qdf_mem_malloc(sizeof(struct peer_ptqm_migrate_list_entry));
 	if (!peer_entry) {
 		mlo_err("Failed to allocate peer entry");
+		status = QDF_STATUS_E_NULL_VALUE;
 		goto exit;
 	}
 
@@ -1689,14 +1692,10 @@ QDF_STATUS wlan_mlo_set_ptqm_migration(struct wlan_objmgr_vdev *vdev,
 						 num_peers_failed);
 	wlan_mlo_free_ptqm_migrate_list(&migrate_list);
 
-	mlo_release_vdev_ref(curr_vdev);
-
-	return status;
-
 exit:
 	if (curr_vdev)
 		mlo_release_vdev_ref(curr_vdev);
 
-	return QDF_STATUS_E_FAILURE;
+	return status;
 }
 #endif /* QCA_SUPPORT_PRIMARY_LINK_MIGRATE */