Sfoglia il codice sorgente

qcacmn: Return on failure of releasing reference of object

The release ref APIs for an object first checks,
if the caller is holding a ref, and if yes, it decrements
the count.

If not, there is an error print and an assert, and if the assert is
disabled, the total ref count is decremented in the code, which could
lead to the object getting destoyed, even when it is being used or
some other component holding its ref.

So, if release ref API for an object is called by a component, which
is not holding the ref, we should return, so its handled correctly
even when assert is disabled.

Change-Id: I90de5c1b2e485e80c4b3138fc0fd99f5509d06a2
CRs-Fixed: 2417616
Vivek 6 anni fa
parent
commit
16ad475315

+ 1 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c

@@ -848,6 +848,7 @@ void wlan_objmgr_pdev_release_ref(struct wlan_objmgr_pdev *pdev,
 		wlan_objmgr_print_ref_ids(pdev->pdev_objmgr.ref_id_dbg,
 					  QDF_TRACE_LEVEL_FATAL);
 		WLAN_OBJMGR_BUG(0);
+		return;
 	}
 
 	if (!qdf_atomic_read(&pdev->pdev_objmgr.ref_cnt)) {

+ 14 - 4
umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c

@@ -646,7 +646,7 @@ QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer,
 qdf_export_symbol(wlan_objmgr_peer_try_get_ref);
 
 #ifdef WLAN_OBJMGR_REF_ID_DEBUG
-static void
+static QDF_STATUS
 wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer,
 				      wlan_objmgr_ref_dbgid id)
 {
@@ -661,19 +661,26 @@ wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer,
 		wlan_objmgr_print_ref_ids(peer->peer_objmgr.ref_id_dbg,
 					  QDF_TRACE_LEVEL_FATAL);
 		WLAN_OBJMGR_BUG(0);
+		return QDF_STATUS_E_FAILURE;
 	}
 
 	qdf_atomic_dec(&peer->peer_objmgr.ref_id_dbg[id]);
+	return QDF_STATUS_SUCCESS;
 }
 #else
-static inline void
+static QDF_STATUS
 wlan_objmgr_peer_release_debug_id_ref(struct wlan_objmgr_peer *peer,
-				      wlan_objmgr_ref_dbgid id) {}
+				      wlan_objmgr_ref_dbgid id)
+{
+	return QDF_STATUS_SUCCESS;
+}
 #endif
 
 void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer,
 				  wlan_objmgr_ref_dbgid id)
 {
+	QDF_STATUS status;
+
 	if (!peer) {
 		obj_mgr_err("peer obj is NULL for %d", id);
 		QDF_ASSERT(0);
@@ -690,7 +697,10 @@ void wlan_objmgr_peer_release_ref(struct wlan_objmgr_peer *peer,
 		WLAN_OBJMGR_BUG(0);
 		return;
 	}
-	wlan_objmgr_peer_release_debug_id_ref(peer, id);
+
+	status = wlan_objmgr_peer_release_debug_id_ref(peer, id);
+	if (QDF_IS_STATUS_ERROR(status))
+		return;
 
 	/* Provide synchronization from the access to add peer
 	 * to logically deleted peer list.

+ 1 - 0
umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c

@@ -874,6 +874,7 @@ void wlan_objmgr_vdev_release_ref(struct wlan_objmgr_vdev *vdev,
 		wlan_objmgr_print_ref_ids(vdev->vdev_objmgr.ref_id_dbg,
 					  QDF_TRACE_LEVEL_FATAL);
 		WLAN_OBJMGR_BUG(0);
+		return;
 	}
 
 	if (!qdf_atomic_read(&vdev->vdev_objmgr.ref_cnt)) {