wlan-ap-Telecominfraproject/feeds/wifi-ax/mac80211/patches/qca/309-ath11k-fix-cpu-stall.patch
John Crispin 8cd26b4b50 ipq807x: update to 11.4-CS
Signed-off-by: John Crispin <john@phrozen.org>
2021-09-14 09:16:23 +02:00

90 lines
2.4 KiB
Diff

From: Karthikeyan Periyasamy <periyasa@codeaurora.org>
Subject: [PATCH] ath11k: avoid RCU cpu stall
The following problems can result in RCU CPU stall warning
1. A CPU looping in an RCU read-side critical section
2. A CPU looping with interrupts disabled
3. A CPU looping with preemption disabled
4. A CPU looping with bottom halves disabled
scenario 1:
As per the above step 4, avoid spin_lock_bh() while
reporting low_ack to user.
scenario 2:
As per the above step 1 & 4, avoid rcu_read_lock() while
reporting mgmt rx through bottom halve disable call ieee80211_rx_ni()
Signed-off-by: Karthikeyan Periyasamy <periyasa@codeaurora.org>
---
--- a/drivers/net/wireless/ath/ath11k/wmi.c
+++ b/drivers/net/wireless/ath/ath11k/wmi.c
@@ -7429,6 +7429,7 @@ static void ath11k_mgmt_rx_event(struct
struct ieee80211_vif *vif;
struct ath11k_vif *arvif;
struct ath11k_mgmt_frame_stats *mgmt_stats;
+ struct ieee80211_hw *hw;
u16 frm_type = 0;
if (ath11k_pull_mgmt_rx_params_tlv(ab, skb, &rx_ev) != 0) {
@@ -7459,6 +7460,8 @@ static void ath11k_mgmt_rx_event(struct
goto exit;
}
+ hw = ar->hw;
+
if (rx_ev.status & WMI_RX_STATUS_ERR_MIC)
status->flag |= RX_FLAG_MMIC_ERROR;
@@ -7559,8 +7562,11 @@ skip_mgmt_stats:
status->freq, status->band, status->signal,
status->rate_idx);
- ieee80211_rx_ni(ar->hw, skb);
+ rcu_read_unlock();
+
+ ieee80211_rx_ni(hw, skb);
+ return;
exit:
rcu_read_unlock();
}
@@ -7913,6 +7919,7 @@ static void ath11k_peer_sta_kickout_even
struct ieee80211_sta *sta;
struct ath11k_peer *peer;
struct ath11k *ar;
+ u32 vdev_id;
if (ath11k_pull_peer_sta_kickout_ev(ab, skb, &arg) != 0) {
ath11k_warn(ab, "failed to extract peer sta kickout event");
@@ -7926,15 +7933,20 @@ static void ath11k_peer_sta_kickout_even
peer = ath11k_peer_find_by_addr(ab, arg.mac_addr);
if (!peer) {
+ spin_unlock_bh(&ab->base_lock);
ath11k_warn(ab, "peer not found %pM\n",
arg.mac_addr);
goto exit;
}
- ar = ath11k_mac_get_ar_by_vdev_id(ab, peer->vdev_id);
+ vdev_id = peer->vdev_id;
+
+ spin_unlock_bh(&ab->base_lock);
+
+ ar = ath11k_mac_get_ar_by_vdev_id(ab, vdev_id);
if (!ar) {
ath11k_warn(ab, "invalid vdev id in peer sta kickout ev %d",
- peer->vdev_id);
+ vdev_id);
goto exit;
}
@@ -7949,7 +7961,6 @@ static void ath11k_peer_sta_kickout_even
ieee80211_report_low_ack(sta, 10);
exit:
- spin_unlock_bh(&ab->base_lock);
rcu_read_unlock();
}