Sfoglia il codice sorgente

qcacmn: keep objmgr_peer alive until txrx peer is freed

Make sure the objmgr_peer is not deleted before
dp peer is deleted, which will avoid the access
of already freed objmgr_peer for connected sta peers.

Change-Id: Ib931dcd0c5650fea5284e9dd53dae9e41f662c56
CRs-Fixed: 2359645
Pavankumar Nandeshwar 6 anni fa
parent
commit
2702aeeb0a

+ 2 - 1
dp/inc/cdp_txrx_ops.h

@@ -852,7 +852,8 @@ struct ol_if_ops {
 					uint8_t vdev_id, uint8_t *peer_macaddr,
 					uint32_t tid_mask);
 	int (*peer_unref_delete)(void *scn_handle, uint8_t *peer_mac,
-				 uint8_t *vdev_mac, enum wlan_op_mode opmode);
+				 uint8_t *vdev_mac, enum wlan_op_mode opmode,
+				 void *old_peer, void *new_peer);
 	bool (*is_hw_dbs_2x2_capable)(struct wlan_objmgr_psoc *psoc);
 	int (*peer_add_wds_entry)(void *vdev_handle,
 				  struct cdp_peer *peer_handle,

+ 12 - 3
dp/wifi3.0/dp_main.c

@@ -4648,7 +4648,7 @@ static void *dp_peer_create_wifi3(struct cdp_vdev *vdev_handle,
 		if (soc->cdp_soc.ol_ops->peer_unref_delete) {
 			soc->cdp_soc.ol_ops->peer_unref_delete(pdev->ctrl_pdev,
 				peer->mac_addr.raw, vdev->mac_addr.raw,
-				vdev->opmode);
+				vdev->opmode, peer->ctrl_peer, ctrl_peer);
 		}
 		peer->ctrl_peer = ctrl_peer;
 
@@ -5146,7 +5146,8 @@ static void dp_reset_and_release_peer_mem(struct dp_soc *soc,
 		m_addr = peer->mac_addr.raw;
 		if (soc->cdp_soc.ol_ops->peer_unref_delete)
 			soc->cdp_soc.ol_ops->peer_unref_delete(pdev->ctrl_pdev,
-				m_addr, vdev->mac_addr.raw, vdev->opmode);
+				m_addr, vdev->mac_addr.raw, vdev->opmode,
+				peer->ctrl_peer, NULL);
 
 		if (vdev && vdev->vap_bss_peer) {
 		    bss_peer = vdev->vap_bss_peer;
@@ -5320,7 +5321,15 @@ static void dp_peer_delete_wifi3(void *peer_handle, uint32_t bitmap)
 	 */
 
 	peer->rx_opt_proc = dp_rx_discard;
-	peer->ctrl_peer = NULL;
+
+	/* Do not make ctrl_peer to NULL for connected sta peers.
+	 * We need ctrl_peer to release the reference during dp
+	 * peer free. This reference was held for
+	 * obj_mgr peer during the creation of dp peer.
+	 */
+	if (!(peer->vdev && (peer->vdev->opmode != wlan_op_mode_sta) &&
+	      !peer->bss_peer))
+		peer->ctrl_peer = NULL;
 
 	QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH,
 		FL("peer %pK (%pM)"),  peer, peer->mac_addr.raw);

+ 4 - 1
umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -229,6 +229,7 @@ typedef void (*wlan_objmgr_peer_status_handler)(
  * @WLAN_MLME_OBJ_DEL_ID:       Object delete req/resp tracking with FW
  * @WLAN_ACTION_OUI_ID:         action oui operations
  * @WLAN_LEGACY_SAP_ID:         legacy sap fsm
+ * @WLAN_TGT_IF_DP_PEER_REF_ID: cp peer reference in dp (Target IF)
  * @WLAN_REF_ID_MAX:            Max id used to generate ref count tracking array
  */
  /* New value added to the enum must also be reflected in function
@@ -280,6 +281,7 @@ typedef enum {
 	WLAN_MLME_OBJ_DEL_ID    = 42,
 	WLAN_ACTION_OUI_ID      = 43,
 	WLAN_LEGACY_SAP_ID      = 44,
+	WLAN_TGT_IF_DP_PEER_REF_ID = 45,
 	WLAN_REF_ID_MAX,
 } wlan_objmgr_ref_dbgid;
 
@@ -338,6 +340,7 @@ static inline char *string_from_dbgid(wlan_objmgr_ref_dbgid id)
 					"WLAN_MLME_OBJ_DEL_ID",
 					"WLAN_ACTION_OUI_ID",
 					"WLAN_LEGACY_SAP_ID",
+					"WLAN_TGT_IF_DP_PEER_REF_ID",
 					"WLAN_REF_ID_MAX"};
 
 	return (char *)strings[id];