diff options
| author | Baochen Qiang <baochen.qiang@oss.qualcomm.com> | 2025-11-19 10:24:47 +0800 |
|---|---|---|
| committer | Jeff Johnson <jeff.johnson@oss.qualcomm.com> | 2025-11-19 11:52:08 -0800 |
| commit | a1e19289932aeef26085feb97597d624da6302ab (patch) | |
| tree | 71f81834b9051b3f5cdc0bde4d09bf5dce91aaa1 /drivers/net/wireless | |
| parent | 5a384854d81f83d59d812b54bfa27fd0e56e36f0 (diff) | |
wifi: ath12k: move firmware stats request outside of atomic context
In ath12k_mac_op_link_sta_statistics(), the atomic context scope
introduced by dp_lock also covers firmware stats request. Since that
request could block, below issue is hit:
BUG: sleeping function called from invalid context at kernel/locking/mutex.c:575
in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 6866, name: iw
preempt_count: 201, expected: 0
RCU nest depth: 0, expected: 0
3 locks held by iw/6866:
#0:[...]
#1:[...]
#2: ffff9748f43230c8 (&dp->dp_lock){+.-.}-{3:3}, at:
ath12k_mac_op_link_sta_statistics+0xc6/0x380 [ath12k]
Preemption disabled at:
[<ffffffffc0349656>] ath12k_mac_op_link_sta_statistics+0xc6/0x380 [ath12k]
Call Trace:
<TASK>
show_stack
dump_stack_lvl
dump_stack
__might_resched.cold
__might_sleep
__mutex_lock
mutex_lock_nested
ath12k_mac_get_fw_stats
ath12k_mac_op_link_sta_statistics
</TASK>
Since firmware stats request doesn't require protection from dp_lock, move
it outside to fix this issue.
While moving, also refine that code hunk to make function parameters get
populated when really necessary.
Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3
Signed-off-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Link: https://patch.msgid.link/20251119-ath12k-ng-sleep-in-atomic-v1-1-5d1a726597db@oss.qualcomm.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless')
| -rw-r--r-- | drivers/net/wireless/ath/ath12k/mac.c | 44 |
1 files changed, 23 insertions, 21 deletions
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index aa80afebb69e..3649f58fef84 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -12792,10 +12792,12 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, db2dbm = test_bit(WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT, ar->ab->wmi_ab.svc_map); - guard(spinlock_bh)(&ar->ab->dp->dp_lock); + spin_lock_bh(&ar->ab->dp->dp_lock); peer = ath12k_dp_link_peer_find_by_addr(ar->ab->dp, arsta->addr); - if (!peer) + if (!peer) { + spin_unlock_bh(&ar->ab->dp->dp_lock); return; + } link_sinfo->rx_duration = peer->rx_duration; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); @@ -12822,35 +12824,35 @@ void ath12k_mac_op_link_sta_statistics(struct ieee80211_hw *hw, link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); } + link_sinfo->signal_avg = ewma_avg_rssi_read(&peer->avg_rssi); + if (!db2dbm) + link_sinfo->signal_avg += ATH12K_DEFAULT_NOISE_FLOOR; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); + + link_sinfo->tx_retries = peer->tx_retry_count; + link_sinfo->tx_failed = peer->tx_retry_failed; + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); + link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + /* TODO: Use real NF instead of default one. */ signal = peer->rssi_comb; - params.pdev_id = ar->pdev->pdev_id; - params.vdev_id = 0; - params.stats_id = WMI_REQUEST_VDEV_STAT; + spin_unlock_bh(&ar->ab->dp->dp_lock); - if (!signal && - ahsta->ahvif->vdev_type == WMI_VDEV_TYPE_STA && - !(ath12k_mac_get_fw_stats(ar, ¶ms))) - signal = arsta->rssi_beacon; + if (!signal && ahsta->ahvif->vdev_type == WMI_VDEV_TYPE_STA) { + params.pdev_id = ar->pdev->pdev_id; + params.vdev_id = 0; + params.stats_id = WMI_REQUEST_VDEV_STAT; + + if (!ath12k_mac_get_fw_stats(ar, ¶ms)) + signal = arsta->rssi_beacon; + } if (signal) { link_sinfo->signal = db2dbm ? signal : signal + ATH12K_DEFAULT_NOISE_FLOOR; link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); } - - link_sinfo->signal_avg = ewma_avg_rssi_read(&peer->avg_rssi); - - if (!db2dbm) - link_sinfo->signal_avg += ATH12K_DEFAULT_NOISE_FLOOR; - - link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG); - - link_sinfo->tx_retries = peer->tx_retry_count; - link_sinfo->tx_failed = peer->tx_retry_failed; - link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_RETRIES); - link_sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); } EXPORT_SYMBOL(ath12k_mac_op_link_sta_statistics); |
