Skip to content

Commit 2e194ef

Browse files
ilanpeer2jmberg-intel
authored andcommitted
wifi: iwlwifi: mvm: Fix race in scan completion
The move of the scan complete notification handling to the wiphy worker introduced a race between scan complete notification and scan abort: - The wiphy lock is held, e.g., for rfkill handling etc. - Scan complete notification is received but not handled yet. - Scan abort is triggered, and scan abort is sent to the FW. Once the scan abort command is sent successfully, the flow synchronously waits for the scan complete notification. However, as the scan complete notification was already received but not processed yet, this hangs for a second and continues leaving the scan status in an inconsistent state. - Once scan complete handling is started (when the wiphy lock is not held) since the scan status is not an inconsistent state, a warning is issued and the scan complete notification is not handled. To fix this issue, switch back the scan complete notification to be asynchronously handling, and only move the link selection logic to a worker (which was the original reason for the move to use wiphy lock). While at it, refactor some prints to improve debug data. Fixes: 07bf529 ("wifi: iwlwifi: mvm: Implement new link selection algorithm") Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://msgid.link/20240506095953.1f484a86324b.I63ed445a47f144546948c74ae6df85587fdb4ce3@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent 05fe960 commit 2e194ef

4 files changed

Lines changed: 55 additions & 29 deletions

File tree

drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,7 @@ void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
13501350
iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_INT_MLO, false);
13511351
mutex_unlock(&mvm->mutex);
13521352

1353+
wiphy_work_cancel(mvm->hw->wiphy, &mvm->trig_link_selection_wk);
13531354
wiphy_work_flush(mvm->hw->wiphy, &mvm->async_handlers_wiphy_wk);
13541355
flush_work(&mvm->async_handlers_wk);
13551356
flush_work(&mvm->add_stream_wk);

drivers/net/wireless/intel/iwlwifi/mvm/mvm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,8 @@ struct iwl_mvm {
937937
/* For async rx handlers that require the wiphy lock */
938938
struct wiphy_work async_handlers_wiphy_wk;
939939

940+
struct wiphy_work trig_link_selection_wk;
941+
940942
struct work_struct roc_done_wk;
941943

942944
unsigned long init_status;

drivers/net/wireless/intel/iwlwifi/mvm/ops.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
383383
iwl_mvm_rx_scan_match_found,
384384
RX_HANDLER_SYNC),
385385
RX_HANDLER(SCAN_COMPLETE_UMAC, iwl_mvm_rx_umac_scan_complete_notif,
386-
RX_HANDLER_ASYNC_LOCKED_WIPHY,
386+
RX_HANDLER_ASYNC_LOCKED,
387387
struct iwl_umac_scan_complete),
388388
RX_HANDLER(SCAN_ITERATION_COMPLETE_UMAC,
389389
iwl_mvm_rx_umac_scan_iter_complete_notif, RX_HANDLER_SYNC,
@@ -1171,6 +1171,27 @@ static const struct iwl_mei_ops mei_ops = {
11711171
.nic_stolen = iwl_mvm_mei_nic_stolen,
11721172
};
11731173

1174+
static void iwl_mvm_find_link_selection_vif(void *_data, u8 *mac,
1175+
struct ieee80211_vif *vif)
1176+
{
1177+
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
1178+
1179+
if (ieee80211_vif_is_mld(vif) && mvmvif->authorized)
1180+
iwl_mvm_select_links(mvmvif->mvm, vif);
1181+
}
1182+
1183+
static void iwl_mvm_trig_link_selection(struct wiphy *wiphy,
1184+
struct wiphy_work *wk)
1185+
{
1186+
struct iwl_mvm *mvm =
1187+
container_of(wk, struct iwl_mvm, trig_link_selection_wk);
1188+
1189+
ieee80211_iterate_active_interfaces(mvm->hw,
1190+
IEEE80211_IFACE_ITER_NORMAL,
1191+
iwl_mvm_find_link_selection_vif,
1192+
NULL);
1193+
}
1194+
11741195
static struct iwl_op_mode *
11751196
iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
11761197
const struct iwl_fw *fw, struct dentry *dbgfs_dir)
@@ -1302,6 +1323,10 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
13021323

13031324
wiphy_work_init(&mvm->async_handlers_wiphy_wk,
13041325
iwl_mvm_async_handlers_wiphy_wk);
1326+
1327+
wiphy_work_init(&mvm->trig_link_selection_wk,
1328+
iwl_mvm_trig_link_selection);
1329+
13051330
init_waitqueue_head(&mvm->rx_sync_waitq);
13061331

13071332
mvm->queue_sync_state = 0;

drivers/net/wireless/intel/iwlwifi/mvm/scan.c

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3178,23 +3178,6 @@ int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
31783178
return ret;
31793179
}
31803180

3181-
static void iwl_mvm_find_link_selection_vif(void *_data, u8 *mac,
3182-
struct ieee80211_vif *vif)
3183-
{
3184-
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3185-
3186-
if (ieee80211_vif_is_mld(vif) && mvmvif->authorized)
3187-
iwl_mvm_select_links(mvmvif->mvm, vif);
3188-
}
3189-
3190-
static void iwl_mvm_post_scan_link_selection(struct iwl_mvm *mvm)
3191-
{
3192-
ieee80211_iterate_active_interfaces(mvm->hw,
3193-
IEEE80211_IFACE_ITER_NORMAL,
3194-
iwl_mvm_find_link_selection_vif,
3195-
NULL);
3196-
}
3197-
31983181
void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
31993182
struct iwl_rx_cmd_buffer *rxb)
32003183
{
@@ -3206,6 +3189,21 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
32063189

32073190
mvm->mei_scan_filter.is_mei_limited_scan = false;
32083191

3192+
IWL_DEBUG_SCAN(mvm,
3193+
"Scan completed: uid=%u type=%u, status=%s, EBS=%s\n",
3194+
uid, mvm->scan_uid_status[uid],
3195+
notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
3196+
"completed" : "aborted",
3197+
iwl_mvm_ebs_status_str(notif->ebs_status));
3198+
3199+
IWL_DEBUG_SCAN(mvm, "Scan completed: scan_status=0x%x\n",
3200+
mvm->scan_status);
3201+
3202+
IWL_DEBUG_SCAN(mvm,
3203+
"Scan completed: line=%u, iter=%u, elapsed time=%u\n",
3204+
notif->last_schedule, notif->last_iter,
3205+
__le32_to_cpu(notif->time_from_last_iter));
3206+
32093207
if (WARN_ON(!(mvm->scan_uid_status[uid] & mvm->scan_status)))
32103208
return;
32113209

@@ -3244,16 +3242,9 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
32443242
}
32453243

32463244
mvm->scan_status &= ~mvm->scan_uid_status[uid];
3247-
IWL_DEBUG_SCAN(mvm,
3248-
"Scan completed, uid %u type %u, status %s, EBS status %s\n",
3249-
uid, mvm->scan_uid_status[uid],
3250-
notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
3251-
"completed" : "aborted",
3252-
iwl_mvm_ebs_status_str(notif->ebs_status));
3253-
IWL_DEBUG_SCAN(mvm,
3254-
"Last line %d, Last iteration %d, Time from last iteration %d\n",
3255-
notif->last_schedule, notif->last_iter,
3256-
__le32_to_cpu(notif->time_from_last_iter));
3245+
3246+
IWL_DEBUG_SCAN(mvm, "Scan completed: after update: scan_status=0x%x\n",
3247+
mvm->scan_status);
32573248

32583249
if (notif->ebs_status != IWL_SCAN_EBS_SUCCESS &&
32593250
notif->ebs_status != IWL_SCAN_EBS_INACTIVE)
@@ -3262,7 +3253,7 @@ void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
32623253
mvm->scan_uid_status[uid] = 0;
32633254

32643255
if (select_links)
3265-
iwl_mvm_post_scan_link_selection(mvm);
3256+
wiphy_work_queue(mvm->hw->wiphy, &mvm->trig_link_selection_wk);
32663257
}
32673258

32683259
void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
@@ -3487,6 +3478,10 @@ int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify)
34873478
{
34883479
int ret;
34893480

3481+
IWL_DEBUG_SCAN(mvm,
3482+
"Request to stop scan: type=0x%x, status=0x%x\n",
3483+
type, mvm->scan_status);
3484+
34903485
if (!(mvm->scan_status & type))
34913486
return 0;
34923487

@@ -3498,6 +3493,9 @@ int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify)
34983493
ret = iwl_mvm_scan_stop_wait(mvm, type);
34993494
if (!ret)
35003495
mvm->scan_status |= type << IWL_MVM_SCAN_STOPPING_SHIFT;
3496+
else
3497+
IWL_DEBUG_SCAN(mvm, "Failed to stop scan\n");
3498+
35013499
out:
35023500
/* Clear the scan status so the next scan requests will
35033501
* succeed and mark the scan as stopping, so that the Rx

0 commit comments

Comments
 (0)