wifi: mac80211_hwsim: avoid calling nlmsg_free() in IRQ or IRQ disabled
authorEN-WEI WU <rickywu0421@gmail.com>
Tue, 15 Aug 2023 09:54:27 +0000 (17:54 +0800)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 22 Aug 2023 19:40:40 +0000 (21:40 +0200)
The nlmsg_free() ends up calling kfree_skb(), and kfree_skb() is not allowed to be called
from hardware interrupt context or with hardware interrupts being disabled. Replace the
mistaken usage of nlmsg_free() by dev_kfree_skb_irq(), which is safe in both cases.

Signed-off-by: EN-WEI WU <enweiwu@FreeBSD.org>
Link: https://lore.kernel.org/r/20230815095427.13589-1-enweiwu@FreeBSD.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/virtual/mac80211_hwsim.c

index dd516ce..ec78fe1 100644 (file)
@@ -6315,7 +6315,7 @@ static void hwsim_virtio_tx_done(struct virtqueue *vq)
 
        spin_lock_irqsave(&hwsim_virtio_lock, flags);
        while ((skb = virtqueue_get_buf(vq, &len)))
-               nlmsg_free(skb);
+               dev_kfree_skb_irq(skb);
        spin_unlock_irqrestore(&hwsim_virtio_lock, flags);
 }
 
@@ -6384,14 +6384,14 @@ static void hwsim_virtio_rx_work(struct work_struct *work)
 
        spin_lock_irqsave(&hwsim_virtio_lock, flags);
        if (!hwsim_virtio_enabled) {
-               nlmsg_free(skb);
+               dev_kfree_skb_irq(skb);
                goto out_unlock;
        }
        vq = hwsim_vqs[HWSIM_VQ_RX];
        sg_init_one(sg, skb->head, skb_end_offset(skb));
        err = virtqueue_add_inbuf(vq, sg, 1, skb, GFP_ATOMIC);
        if (WARN(err, "virtqueue_add_inbuf returned %d\n", err))
-               nlmsg_free(skb);
+               dev_kfree_skb_irq(skb);
        else
                virtqueue_kick(vq);
        schedule_work(&hwsim_virtio_rx);