瀏覽代碼

qcacmn: Avoid deadlock between ML AP VDEVs bring up

1. Start response is received for vdev-0 and continues processing
mlo_sync_complete for partner vdevs holding ap_ctx lock and waiting
on vdev_sm lock of partner vdev
2. During which one of the partner vdev completes CAC_WAIT and continues
processing mlo_sync_complete holding vdev_sm lock and
waiting on ap_ctx lock. This scenario is resulting in RCU_STALL.

The last vdev in MLD to receive start response is responsible for
dispatching MLO_SYNC_COMPLETE event all the partner vdevs and then to self
If vdev_up_bmap is set, then return.

Change-Id: I5ae7146eeba5154331f442f9987593044bde76b4
CRs-Fixed: 3457019
Santosh Anbu 2 年之前
父節點
當前提交
be9367e046
共有 1 個文件被更改,包括 23 次插入1 次删除
  1. 23 1
      umac/mlo_mgr/src/wlan_mlo_mgr_ap.c

+ 23 - 1
umac/mlo_mgr/src/wlan_mlo_mgr_ap.c

@@ -332,6 +332,7 @@ static bool mlo_handle_link_ready(struct wlan_objmgr_vdev *vdev)
 	uint8_t i;
 	uint8_t idx;
 	enum wlan_vdev_state state;
+	enum wlan_vdev_state substate;
 
 
 	if (!vdev || !vdev->mlo_dev_ctx) {
@@ -340,9 +341,28 @@ static bool mlo_handle_link_ready(struct wlan_objmgr_vdev *vdev)
 	}
 
 	mld_ctx = vdev->mlo_dev_ctx;
+	/*
+	 * The last vdev in MLD to receive start response is responsible for
+	 * dispatching MLO_SYNC_COMPLETE event all the partner vdevs and then to
+	 * self.
+	 *
+	 * If vdev_up_bmap is set, then return.
+	 */
+	idx = mlo_get_link_vdev_ix(mld_ctx, vdev);
+	if (idx == MLO_INVALID_LINK_IDX)
+		return false;
+
+	if (wlan_util_map_index_is_set(mld_ctx->ap_ctx->mlo_vdev_up_bmap,
+				       idx)) {
+		mlo_debug("Bmap is set for idx:%u mld_addr " QDF_MAC_ADDR_FMT,
+			  idx, QDF_MAC_ADDR_REF(mld_ctx->mld_addr.bytes));
+		return false;
+	}
+
 	mlo_ap_lock_acquire(vdev->mlo_dev_ctx->ap_ctx);
 	state = wlan_vdev_mlme_get_state(vdev);
-	if (state == WLAN_VDEV_S_UP) {
+	substate = wlan_vdev_mlme_get_substate(vdev);
+	if (state == WLAN_VDEV_S_UP && substate == WLAN_VDEV_SS_MLO_SYNC_WAIT) {
 		idx = mlo_get_link_vdev_ix(mld_ctx, vdev);
 		if (idx == MLO_INVALID_LINK_IDX) {
 			mlo_ap_lock_release(vdev->mlo_dev_ctx->ap_ctx);
@@ -350,6 +370,8 @@ static bool mlo_handle_link_ready(struct wlan_objmgr_vdev *vdev)
 		}
 		wlan_util_change_map_index(mld_ctx->ap_ctx->mlo_vdev_up_bmap,
 					   idx, 1);
+		mlo_debug("Setting Bmap for idx:%u mld_addr " QDF_MAC_ADDR_FMT,
+			  idx, QDF_MAC_ADDR_REF(mld_ctx->mld_addr.bytes));
 	}
 
 	if (!mlo_is_ap_vdev_up_allowed(vdev)) {