Message ID | 20221207141411.46098-2-yangyingliang@huawei.com |
---|---|
State | Superseded |
Headers | show |
Series | wifi: rtlwifi: don't call kfree_skb() under spin_lock_irqsave() | expand |
Yang Yingliang <yangyingliang@huawei.com> wrote: > It is not allowed to call kfree_skb() from hardware interrupt > context or with interrupts being disabled. All the SKBs have > been dequeued from the old queue, so it's safe to enqueue these > SKBs to a free queue, then free them after spin_unlock_irqrestore() > at once. Compile tested only. > > Fixes: 5c99f04fec93 ("rtlwifi: rtl8723be: Update driver to match Realtek release of 06/28/14") > Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> > Acked-by: Ping-Ke Shih <pkshih@realtek.com> 3 patches applied to wireless-next.git, thanks. 106031c1f4a8 wifi: rtlwifi: rtl8821ae: don't call kfree_skb() under spin_lock_irqsave() 2611687fa7ff wifi: rtlwifi: rtl8188ee: don't call kfree_skb() under spin_lock_irqsave() 313950c2114e wifi: rtlwifi: rtl8723be: don't call kfree_skb() under spin_lock_irqsave()
diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c index 7e0f62d59fe1..a7e3250957dc 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c @@ -26,8 +26,10 @@ static void _rtl8821ae_return_beacon_queue_skb(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE]; + struct sk_buff_head free_list; unsigned long flags; + skb_queue_head_init(&free_list); spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); while (skb_queue_len(&ring->queue)) { struct rtl_tx_desc *entry = &ring->desc[ring->idx]; @@ -37,10 +39,12 @@ static void _rtl8821ae_return_beacon_queue_skb(struct ieee80211_hw *hw) rtlpriv->cfg->ops->get_desc(hw, (u8 *)entry, true, HW_DESC_TXBUFF_ADDR), skb->len, DMA_TO_DEVICE); - kfree_skb(skb); + __skb_queue_tail(&free_list, skb); ring->idx = (ring->idx + 1) % ring->entries; } spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); + + __skb_queue_purge(&free_list); } static void _rtl8821ae_set_bcn_ctrl_reg(struct ieee80211_hw *hw,