Browse Source

qcacmn: Access only created objects

Accessing partially created objects are leading to freeing the
objects due to uninitialized ref count

Fix checks the valid object state to
	1) invoke the handler on the object for iterate API
	2) get reference of the object

Change-Id: I479d68a57e16b0eb679d3a8c3e45cd924a7cff3e
CRs-Fixed: 2161085
Srinivas Pitla 7 years ago
parent
commit
86db6ab400

+ 11 - 8
umac/cmn_services/obj_mgr/inc/wlan_objmgr_cmn.h

@@ -62,6 +62,8 @@
 
 /**
  * enum WLAN_OBJ_STATE - State of Object
+ * @WLAN_OBJ_STATE_ALLOCATED:           Common object is allocated, but not
+ *                                      fully initialized
  * @WLAN_OBJ_STATE_CREATED:             All component objects are created
  * @WLAN_OBJ_STATE_DELETED:             All component objects are destroyed
  * @WLAN_OBJ_STATE_PARTIALLY_CREATED:   Few/All component objects creation is
@@ -82,14 +84,15 @@
  *                                      destroyed
  */
 typedef enum {
-	WLAN_OBJ_STATE_CREATED            = 0,
-	WLAN_OBJ_STATE_DELETED            = 1,
-	WLAN_OBJ_STATE_PARTIALLY_CREATED  = 2,
-	WLAN_OBJ_STATE_PARTIALLY_DELETED  = 3,
-	WLAN_OBJ_STATE_COMP_DEL_PROGRESS  = 4,
-	WLAN_OBJ_STATE_LOGICALLY_DELETED  = 5,
-	WLAN_OBJ_STATE_CREATION_FAILED    = 6,
-	WLAN_OBJ_STATE_DELETION_FAILED    = 7,
+	WLAN_OBJ_STATE_ALLOCATED          = 0,
+	WLAN_OBJ_STATE_CREATED            = 1,
+	WLAN_OBJ_STATE_DELETED            = 2,
+	WLAN_OBJ_STATE_PARTIALLY_CREATED  = 3,
+	WLAN_OBJ_STATE_PARTIALLY_DELETED  = 4,
+	WLAN_OBJ_STATE_COMP_DEL_PROGRESS  = 5,
+	WLAN_OBJ_STATE_LOGICALLY_DELETED  = 6,
+	WLAN_OBJ_STATE_CREATION_FAILED    = 7,
+	WLAN_OBJ_STATE_DELETION_FAILED    = 8,
 } WLAN_OBJ_STATE;
 
 /* Object type is assigned with value */

+ 6 - 5
umac/cmn_services/obj_mgr/src/wlan_objmgr_pdev_obj.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 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
@@ -110,6 +110,7 @@ struct wlan_objmgr_pdev *wlan_objmgr_pdev_obj_create(
 		obj_mgr_err("pdev alloc failed");
 		return NULL;
 	}
+	pdev->obj_state = WLAN_OBJ_STATE_ALLOCATED;
 	/* Attach PDEV with PSOC */
 	if (wlan_objmgr_psoc_pdev_attach(psoc, pdev)
 				!= QDF_STATUS_SUCCESS) {
@@ -824,13 +825,13 @@ QDF_STATUS wlan_objmgr_pdev_try_get_ref(struct wlan_objmgr_pdev *pdev,
 
 	wlan_pdev_obj_lock(pdev);
 	pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
-	if (pdev->obj_state == WLAN_OBJ_STATE_LOGICALLY_DELETED) {
+	if (pdev->obj_state != WLAN_OBJ_STATE_CREATED) {
 		wlan_pdev_obj_unlock(pdev);
 		if (pdev->pdev_objmgr.print_cnt++ <=
 				WLAN_OBJMGR_RATELIMIT_THRESH)
-			obj_mgr_err("[Ref id: %d] pdev [%d] is in L-Del state",
-					id, pdev_id);
-
+			obj_mgr_err(
+			"[Ref id: %d] pdev [%d] is not in Created(st:%d)",
+					id, pdev_id, pdev->obj_state);
 		return QDF_STATUS_E_RESOURCES;
 	}
 

+ 7 - 6
umac/cmn_services/obj_mgr/src/wlan_objmgr_peer_obj.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 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
@@ -167,6 +167,7 @@ struct wlan_objmgr_peer *wlan_objmgr_peer_obj_create(
 				macaddr[3], macaddr[4], macaddr[5]);
 		return NULL;
 	}
+	peer->obj_state = WLAN_OBJ_STATE_ALLOCATED;
 	qdf_atomic_init(&peer->peer_objmgr.ref_cnt);
 	for (id = 0; id < WLAN_REF_ID_MAX; id++)
 		qdf_atomic_init(&peer->peer_objmgr.ref_id_dbg[id]);
@@ -592,14 +593,14 @@ QDF_STATUS wlan_objmgr_peer_try_get_ref(struct wlan_objmgr_peer *peer,
 
 	wlan_peer_obj_lock(peer);
 	macaddr = wlan_peer_get_macaddr(peer);
-	if (peer->obj_state == WLAN_OBJ_STATE_LOGICALLY_DELETED) {
+	if (peer->obj_state != WLAN_OBJ_STATE_CREATED) {
 		wlan_peer_obj_unlock(peer);
 		if (peer->peer_objmgr.print_cnt++ <=
 				WLAN_OBJMGR_RATELIMIT_THRESH)
-			obj_mgr_err("peer(%02x:%02x:%02x:%02x:%02x:%02x) L-Del",
-				macaddr[0], macaddr[1], macaddr[2],
-				macaddr[3], macaddr[4], macaddr[5]);
-
+			obj_mgr_err(
+			"peer(" QDF_MAC_ADDRESS_STR ") not in Created st(%d)",
+			QDF_MAC_ADDR_ARRAY(macaddr),
+				peer->obj_state);
 		return QDF_STATUS_E_RESOURCES;
 	}
 

+ 10 - 9
umac/cmn_services/obj_mgr/src/wlan_objmgr_psoc_obj.c

@@ -123,6 +123,7 @@ struct wlan_objmgr_psoc *wlan_objmgr_psoc_obj_create(uint32_t phy_version,
 		obj_mgr_err("PSOC allocation failed");
 		return NULL;
 	}
+	psoc->obj_state = WLAN_OBJ_STATE_ALLOCATED;
 	qdf_spinlock_create(&psoc->psoc_lock);
 	/* Initialize with default values */
 	objmgr = &psoc->soc_objmgr;
@@ -425,9 +426,8 @@ QDF_STATUS wlan_objmgr_iterate_obj_list(
 		for (obj_id = 0; obj_id < WLAN_UMAC_MAX_PDEVS; obj_id++) {
 			pdev = objmgr->wlan_pdev_list[obj_id];
 			if ((pdev != NULL) &&
-			    (pdev->obj_state !=
-				WLAN_OBJ_STATE_LOGICALLY_DELETED)) {
-				wlan_objmgr_pdev_get_ref(pdev, dbg_id);
+			    (wlan_objmgr_pdev_try_get_ref(pdev, dbg_id) ==
+				QDF_STATUS_SUCCESS)) {
 				handler(psoc, (void *)pdev, arg);
 				wlan_objmgr_pdev_release_ref(pdev, dbg_id);
 			}
@@ -438,9 +438,8 @@ QDF_STATUS wlan_objmgr_iterate_obj_list(
 		for (obj_id = 0; obj_id < WLAN_UMAC_PSOC_MAX_VDEVS; obj_id++) {
 			vdev = objmgr->wlan_vdev_list[obj_id];
 			if ((vdev != NULL) &&
-			    (vdev->obj_state !=
-				WLAN_OBJ_STATE_LOGICALLY_DELETED)) {
-				wlan_objmgr_vdev_get_ref(vdev, dbg_id);
+			    (wlan_objmgr_vdev_try_get_ref(vdev, dbg_id) ==
+				QDF_STATUS_SUCCESS)) {
 				handler(psoc, vdev, arg);
 				wlan_objmgr_vdev_release_ref(vdev, dbg_id);
 			}
@@ -1703,11 +1702,13 @@ QDF_STATUS wlan_objmgr_psoc_try_get_ref(struct wlan_objmgr_psoc *psoc,
 	}
 
 	wlan_psoc_obj_lock(psoc);
-	if (psoc->obj_state == WLAN_OBJ_STATE_LOGICALLY_DELETED) {
+	if (psoc->obj_state != WLAN_OBJ_STATE_CREATED) {
 		wlan_psoc_obj_unlock(psoc);
 		if (psoc->soc_objmgr.print_cnt++ <=
 				WLAN_OBJMGR_RATELIMIT_THRESH)
-			obj_mgr_err("[Ref id: %d] psoc is in L-Del state", id);
+			obj_mgr_err(
+			"[Ref id: %d] psoc is not in Created state(%d)",
+					id, psoc->obj_state);
 
 		return QDF_STATUS_E_RESOURCES;
 	}
@@ -1827,7 +1828,7 @@ QDF_STATUS wlan_objmgr_psoc_set_user_config(struct wlan_objmgr_psoc *psoc,
 	}
 	wlan_psoc_obj_lock(psoc);
 	qdf_mem_copy(&psoc->soc_nif.user_config, user_config_data,
-				sizeof(psoc->soc_nif.user_config));
+		     sizeof(psoc->soc_nif.user_config));
 	wlan_psoc_obj_unlock(psoc);
 
 	return QDF_STATUS_SUCCESS;

+ 9 - 7
umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018 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
@@ -134,6 +134,7 @@ struct wlan_objmgr_vdev *wlan_objmgr_vdev_obj_create(
 		obj_mgr_err("Memory allocation failure");
 		return NULL;
 	}
+	vdev->obj_state = WLAN_OBJ_STATE_ALLOCATED;
 	/* Attach VDEV to PSOC VDEV's list */
 	if (wlan_objmgr_psoc_vdev_attach(psoc, vdev) !=
 				QDF_STATUS_SUCCESS) {
@@ -460,10 +461,10 @@ QDF_STATUS wlan_objmgr_iterate_peerobj_list(
 	wlan_vdev_obj_lock(vdev);
 	vdev_id = wlan_vdev_get_id(vdev);
 
-	if (vdev->obj_state ==
-		WLAN_OBJ_STATE_LOGICALLY_DELETED) {
+	if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
 		wlan_vdev_obj_unlock(vdev);
-		obj_mgr_err("VDEV is in delete progress: vdev-id:%d", vdev_id);
+		obj_mgr_err("VDEV is not in create state(:%d): vdev-id:%d",
+				vdev_id, vdev->obj_state);
 		return QDF_STATUS_E_FAILURE;
 	}
 	wlan_objmgr_vdev_get_ref(vdev, dbg_id);
@@ -742,12 +743,13 @@ QDF_STATUS wlan_objmgr_vdev_try_get_ref(struct wlan_objmgr_vdev *vdev,
 
 	wlan_vdev_obj_lock(vdev);
 	vdev_id = wlan_vdev_get_id(vdev);
-	if (vdev->obj_state == WLAN_OBJ_STATE_LOGICALLY_DELETED) {
+	if (vdev->obj_state != WLAN_OBJ_STATE_CREATED) {
 		wlan_vdev_obj_unlock(vdev);
 		if (vdev->vdev_objmgr.print_cnt++ <=
 				WLAN_OBJMGR_RATELIMIT_THRESH)
-			obj_mgr_err("[Ref id: %d] vdev(%d) is in Log Del",
-				id, vdev_id);
+			obj_mgr_err(
+			"[Ref id: %d] vdev(%d) is not in Created state(%d)",
+				id, vdev_id, vdev->obj_state);
 
 		return QDF_STATUS_E_RESOURCES;
 	}