qcacmn: Add vdev up bitmap for mlo sync wait state handling
In MLO scenario where start/cac response for partner ML AP vdevs are processed simultaneously on different CPU cores, the order in which the vdev sm lock is acquired may lead to deadlock. To fix add change to have vdev up bitmap and process sync complete only for those vdevs for which the bitmap is set Change-Id: I9ca8b192edeb7d491be3a7acff30c2d3545a5417 CRs-Fixed: 3403603
このコミットが含まれているのは:
@@ -325,6 +325,7 @@ struct wlan_mlo_sta {
|
||||
* @ml_aid_mgr: ML AID mgr
|
||||
* @mlo_ap_lock: lock to sync VDEV SM event
|
||||
* @mlo_vdev_quiet_bmap: Bitmap of vdevs for which quiet ie needs to enabled
|
||||
* @mlo_vdev_up_bmap: Bitmap of vdevs for which sync complete can be dispatched
|
||||
*
|
||||
* NB: not using kernel-doc format since the kernel-doc script doesn't
|
||||
* handle the qdf_bitmap() macro
|
||||
@@ -338,6 +339,7 @@ struct wlan_mlo_ap {
|
||||
qdf_mutex_t mlo_ap_lock;
|
||||
#endif
|
||||
qdf_bitmap(mlo_vdev_quiet_bmap, WLAN_UMAC_MLO_MAX_VDEVS);
|
||||
qdf_bitmap(mlo_vdev_up_bmap, WLAN_UMAC_MLO_MAX_VDEVS);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -327,27 +327,59 @@ static bool mlo_pre_link_up(struct wlan_objmgr_vdev *vdev)
|
||||
static bool mlo_handle_link_ready(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev_list[WLAN_UMAC_MLO_MAX_VDEVS] = {NULL};
|
||||
struct wlan_mlo_dev_context *mld_ctx = NULL;
|
||||
uint16_t num_links = 0;
|
||||
uint8_t i;
|
||||
uint8_t idx;
|
||||
enum wlan_vdev_state state;
|
||||
|
||||
|
||||
if (!vdev || !vdev->mlo_dev_ctx) {
|
||||
mlo_err("Invalid input");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mlo_is_ap_vdev_up_allowed(vdev))
|
||||
mld_ctx = vdev->mlo_dev_ctx;
|
||||
mlo_ap_lock_acquire(vdev->mlo_dev_ctx->ap_ctx);
|
||||
state = wlan_vdev_mlme_get_state(vdev);
|
||||
if (state == WLAN_VDEV_S_UP) {
|
||||
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);
|
||||
return false;
|
||||
}
|
||||
wlan_util_change_map_index(mld_ctx->ap_ctx->mlo_vdev_up_bmap,
|
||||
idx, 1);
|
||||
}
|
||||
|
||||
if (!mlo_is_ap_vdev_up_allowed(vdev)) {
|
||||
mlo_ap_lock_release(vdev->mlo_dev_ctx->ap_ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
mlo_ap_get_vdev_list(vdev, &num_links, vdev_list);
|
||||
if (!num_links || (num_links > QDF_ARRAY_SIZE(vdev_list))) {
|
||||
mlo_err("Invalid number of VDEVs under AP-MLD");
|
||||
mlo_ap_lock_release(vdev->mlo_dev_ctx->ap_ctx);
|
||||
return false;
|
||||
}
|
||||
|
||||
mlo_ap_lock_acquire(vdev->mlo_dev_ctx->ap_ctx);
|
||||
for (i = 0; i < num_links; i++) {
|
||||
if (mlo_pre_link_up(vdev_list[i])) {
|
||||
if (vdev_list[i] != vdev)
|
||||
if (vdev_list[i] == vdev) {
|
||||
mlo_release_vdev_ref(vdev_list[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
idx = mlo_get_link_vdev_ix(mld_ctx, vdev_list[i]);
|
||||
if (idx == MLO_INVALID_LINK_IDX) {
|
||||
mlo_release_vdev_ref(vdev_list[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (wlan_util_map_index_is_set(
|
||||
vdev->mlo_dev_ctx->ap_ctx->mlo_vdev_up_bmap,
|
||||
idx))
|
||||
wlan_vdev_mlme_sm_deliver_evt(
|
||||
vdev_list[i],
|
||||
WLAN_VDEV_SM_EV_MLO_SYNC_COMPLETE,
|
||||
|
新しいイシューから参照
ユーザーをブロックする