mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
wifi: ath10k: avoid IDR mutation during TX cleanup
ath10k_htt_flush_tx_queue() walks pending_tx with idr_for_each().
Its callback calls ath10k_txrx_tx_unref(), which removes the current
entry from pending_tx through ath10k_htt_tx_free_msdu_id().
idr_for_each() keeps radix-tree iterator state across the callback.
Removing the current entry can therefore invalidate that state and
make the remaining walk unsafe.
Use idr_for_each_entry(), which starts a fresh lookup after each
callback. The current entry can then be removed safely, while the
following idr_destroy() continues to release the IDR itself.
Fixes: 89d6d83565 ("ath10k: use idr api for msdu_ids")
Signed-off-by: Jiale Yao <yaojiale02@163.com>
Reviewed-by: Baochen Qiang <baochen.qiang@oss.qualcomm.com>
Reviewed-by: Rameshkumar Sundaram <rameshkumar.sundaram@oss.qualcomm.com>
Link: https://patch.msgid.link/20261003092104.520135-2-yaojiale02@163.com
[changed ath10k_htt_tx_clean_up_pending() signature]
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
parent
ebc938ba1d
commit
1c1a208e65
|
|
@ -505,9 +505,8 @@ int ath10k_htt_tx_start(struct ath10k_htt *htt)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_htt_tx_clean_up_pending(int msdu_id, void *skb, void *ctx)
|
||||
static void ath10k_htt_tx_clean_up_pending(int msdu_id, struct ath10k *ar)
|
||||
{
|
||||
struct ath10k *ar = ctx;
|
||||
struct ath10k_htt *htt = &ar->htt;
|
||||
struct htt_tx_done tx_done = {};
|
||||
|
||||
|
|
@ -517,8 +516,6 @@ static int ath10k_htt_tx_clean_up_pending(int msdu_id, void *skb, void *ctx)
|
|||
tx_done.status = HTT_TX_COMPL_STATE_DISCARD;
|
||||
|
||||
ath10k_txrx_tx_unref(htt, &tx_done);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath10k_htt_tx_destroy(struct ath10k_htt *htt)
|
||||
|
|
@ -535,8 +532,13 @@ void ath10k_htt_tx_destroy(struct ath10k_htt *htt)
|
|||
|
||||
static void ath10k_htt_flush_tx_queue(struct ath10k_htt *htt)
|
||||
{
|
||||
struct sk_buff *msdu;
|
||||
int msdu_id;
|
||||
|
||||
ath10k_htc_stop_hl(htt->ar);
|
||||
idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar);
|
||||
|
||||
idr_for_each_entry(&htt->pending_tx, msdu, msdu_id)
|
||||
ath10k_htt_tx_clean_up_pending(msdu_id, htt->ar);
|
||||
}
|
||||
|
||||
void ath10k_htt_tx_stop(struct ath10k_htt *htt)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user