Browse Source

qcacmn: Acquire pdev lock on updating pdev peer count

The pdev peer count needs to be updated with pdev lock, as multiple peers
can be created same time, which can result in synchronization issues
without lock

Change-Id: Ic8164585873f32a801dd9a334f861d6666b9864f
CRs-Fixed: 2203011
Srinivas Pitla 7 years ago
parent
commit
9578a90c65
1 changed files with 19 additions and 5 deletions
  1. 19 5
      umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c

+ 19 - 5
umac/cmn_services/obj_mgr/src/wlan_objmgr_vdev_obj.c

@@ -646,16 +646,24 @@ QDF_STATUS wlan_objmgr_vdev_peer_attach(struct wlan_objmgr_vdev *vdev,
 	wlan_vdev_obj_lock(vdev);
 	pdev = wlan_vdev_get_pdev(vdev);
 	/* If Max peer count exceeds, return failure */
-	if ((objmgr->wlan_peer_count >= objmgr->max_peer_count) ||
-	     (wlan_pdev_get_peer_count(pdev) >=
-			wlan_pdev_get_max_peer_count(pdev))) {
+	if (objmgr->wlan_peer_count >= objmgr->max_peer_count) {
 		wlan_vdev_obj_unlock(vdev);
 		return QDF_STATUS_E_FAILURE;
 	}
+
+	wlan_pdev_obj_lock(pdev);
+	if (wlan_pdev_get_peer_count(pdev) >=
+			wlan_pdev_get_max_peer_count(pdev)) {
+		wlan_pdev_obj_unlock(pdev);
+		wlan_vdev_obj_unlock(vdev);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	wlan_pdev_incr_peer_count(wlan_vdev_get_pdev(vdev));
+	wlan_pdev_obj_unlock(pdev);
 	/* Add peer to vdev's peer list */
 	wlan_obj_vdev_peerlist_add_tail(&objmgr->wlan_peer_list, peer);
 	objmgr->wlan_peer_count++;
-	wlan_pdev_incr_peer_count(wlan_vdev_get_pdev(vdev));
 
 	if (WLAN_ADDR_EQ(wlan_peer_get_macaddr(peer),
 			 wlan_vdev_mlme_get_macaddr(vdev)) ==
@@ -685,6 +693,7 @@ QDF_STATUS wlan_objmgr_vdev_peer_detach(struct wlan_objmgr_vdev *vdev,
 					struct wlan_objmgr_peer *peer)
 {
 	struct wlan_objmgr_vdev_objmgr *objmgr = &vdev->vdev_objmgr;
+	struct wlan_objmgr_pdev *pdev;
 
 	wlan_vdev_obj_lock(vdev);
 	/* if peer count is 0, return failure */
@@ -726,7 +735,12 @@ QDF_STATUS wlan_objmgr_vdev_peer_detach(struct wlan_objmgr_vdev *vdev,
 	}
 	/* decrement peer count */
 	objmgr->wlan_peer_count--;
-	wlan_pdev_decr_peer_count(wlan_vdev_get_pdev(vdev));
+	/* decrement pdev peer count */
+	pdev = wlan_vdev_get_pdev(vdev);
+	wlan_pdev_obj_lock(pdev);
+	wlan_pdev_decr_peer_count(pdev);
+	wlan_pdev_obj_unlock(pdev);
+
 	wlan_vdev_obj_unlock(vdev);
 	/* decrement vdev ref count after peer released its reference */
 	wlan_objmgr_vdev_release_ref(vdev, WLAN_OBJMGR_ID);