mt76: disable BH around napi_schedule() calls
authorFelix Fietkau <nbd@nbd.name>
Fri, 24 Sep 2021 15:54:40 +0000 (17:54 +0200)
committerFelix Fietkau <nbd@nbd.name>
Wed, 20 Oct 2021 08:36:39 +0000 (10:36 +0200)
napi_schedule() can call __raise_softirq_irqoff(), which can perform softirq
handling, so it must not be called in a pure process context with BH enabled.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7603/mac.c
drivers/net/wireless/mediatek/mt76/mt7615/pci.c
drivers/net/wireless/mediatek/mt76/mt7615/pci_mac.c
drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
drivers/net/wireless/mediatek/mt76/mt76x02_mmio.c
drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
drivers/net/wireless/mediatek/mt76/mt7915/mac.c
drivers/net/wireless/mediatek/mt76/mt7921/mac.c
drivers/net/wireless/mediatek/mt76/mt7921/pci.c

index 3972c56..d1cbe06 100644 (file)
@@ -1471,17 +1471,20 @@ skip_dma_reset:
        mutex_unlock(&dev->mt76.mutex);
 
        mt76_worker_enable(&dev->mt76.tx_worker);
-       napi_enable(&dev->mt76.tx_napi);
-       napi_schedule(&dev->mt76.tx_napi);
 
        tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
        mt7603_beacon_set_timer(dev, -1, beacon_int);
 
+       local_bh_disable();
+       napi_enable(&dev->mt76.tx_napi);
+       napi_schedule(&dev->mt76.tx_napi);
+
        napi_enable(&dev->mt76.napi[0]);
        napi_schedule(&dev->mt76.napi[0]);
 
        napi_enable(&dev->mt76.napi[1]);
        napi_schedule(&dev->mt76.napi[1]);
+       local_bh_enable();
 
        ieee80211_wake_queues(dev->mt76.hw);
        mt76_txq_schedule_all(&dev->mphy);
index 7a54ea6..b808248 100644 (file)
@@ -164,12 +164,14 @@ static int mt7615_pci_resume(struct pci_dev *pdev)
                dev_err(mdev->dev, "PDMA engine must be reinitialized\n");
 
        mt76_worker_enable(&mdev->tx_worker);
+       local_bh_disable();
        mt76_for_each_q_rx(mdev, i) {
                napi_enable(&mdev->napi[i]);
                napi_schedule(&mdev->napi[i]);
        }
        napi_enable(&mdev->tx_napi);
        napi_schedule(&mdev->tx_napi);
+       local_bh_enable();
 
        if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) &&
            mt7615_firmware_offload(dev))
index da87c02..0a4cadd 100644 (file)
@@ -326,6 +326,8 @@ void mt7615_mac_reset_work(struct work_struct *work)
                clear_bit(MT76_RESET, &phy2->mt76->state);
 
        mt76_worker_enable(&dev->mt76.tx_worker);
+
+       local_bh_disable();
        napi_enable(&dev->mt76.tx_napi);
        napi_schedule(&dev->mt76.tx_napi);
 
@@ -334,6 +336,7 @@ void mt7615_mac_reset_work(struct work_struct *work)
 
        napi_enable(&dev->mt76.napi[1]);
        napi_schedule(&dev->mt76.napi[1]);
+       local_bh_enable();
 
        ieee80211_wake_queues(mt76_hw(dev));
        if (ext_phy)
index 92ddb8c..f19228f 100644 (file)
@@ -276,6 +276,7 @@ static int mt76x0e_resume(struct pci_dev *pdev)
 
        mt76_worker_enable(&mdev->tx_worker);
 
+       local_bh_disable();
        mt76_for_each_q_rx(mdev, i) {
                mt76_queue_rx_reset(dev, i);
                napi_enable(&mdev->napi[i]);
@@ -284,6 +285,7 @@ static int mt76x0e_resume(struct pci_dev *pdev)
 
        napi_enable(&mdev->tx_napi);
        napi_schedule(&mdev->tx_napi);
+       local_bh_enable();
 
        return mt76x0e_init_hardware(dev, true);
 }
index b50084b..f4451fb 100644 (file)
@@ -491,15 +491,17 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
        clear_bit(MT76_RESET, &dev->mphy.state);
 
        mt76_worker_enable(&dev->mt76.tx_worker);
+       tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
+
+       local_bh_disable();
        napi_enable(&dev->mt76.tx_napi);
        napi_schedule(&dev->mt76.tx_napi);
 
-       tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
-
        mt76_for_each_q_rx(&dev->mt76, i) {
                napi_enable(&dev->mt76.napi[i]);
                napi_schedule(&dev->mt76.napi[i]);
        }
+       local_bh_enable();
 
        if (restart) {
                set_bit(MT76_RESTART, &dev->mphy.state);
index fb8de18..8a22ee5 100644 (file)
@@ -149,12 +149,15 @@ mt76x2e_resume(struct pci_dev *pdev)
        pci_restore_state(pdev);
 
        mt76_worker_enable(&mdev->tx_worker);
+
+       local_bh_disable();
        mt76_for_each_q_rx(mdev, i) {
                napi_enable(&mdev->napi[i]);
                napi_schedule(&mdev->napi[i]);
        }
        napi_enable(&mdev->tx_napi);
        napi_schedule(&mdev->tx_napi);
+       local_bh_enable();
 
        return mt76x2_resume_device(dev);
 }
index 02e2b8f..81cde3c 100644 (file)
@@ -1837,6 +1837,7 @@ void mt7915_mac_reset_work(struct work_struct *work)
        if (phy2)
                clear_bit(MT76_RESET, &phy2->mt76->state);
 
+       local_bh_disable();
        napi_enable(&dev->mt76.napi[0]);
        napi_schedule(&dev->mt76.napi[0]);
 
@@ -1845,6 +1846,8 @@ void mt7915_mac_reset_work(struct work_struct *work)
 
        napi_enable(&dev->mt76.napi[2]);
        napi_schedule(&dev->mt76.napi[2]);
+       local_bh_enable();
+
        tasklet_schedule(&dev->irq_tasklet);
 
        mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
index 99db8c6..4023e0a 100644 (file)
@@ -1390,10 +1390,12 @@ mt7921_mac_reset(struct mt7921_dev *dev)
 
        mt7921_wpdma_reset(dev, true);
 
+       local_bh_disable();
        mt76_for_each_q_rx(&dev->mt76, i) {
                napi_enable(&dev->mt76.napi[i]);
                napi_schedule(&dev->mt76.napi[i]);
        }
+       local_bh_enable();
 
        clear_bit(MT76_MCU_RESET, &dev->mphy.state);
 
@@ -1418,8 +1420,11 @@ mt7921_mac_reset(struct mt7921_dev *dev)
 out:
        clear_bit(MT76_RESET, &dev->mphy.state);
 
+       local_bh_disable();
        napi_enable(&dev->mt76.tx_napi);
        napi_schedule(&dev->mt76.tx_napi);
+       local_bh_enable();
+
        mt76_worker_enable(&dev->mt76.tx_worker);
 
        return err;
index 44075f8..b5622b6 100644 (file)
@@ -302,12 +302,15 @@ static int mt7921_pci_resume(struct pci_dev *pdev)
                 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
 
        mt76_worker_enable(&mdev->tx_worker);
+
+       local_bh_disable();
        mt76_for_each_q_rx(mdev, i) {
                napi_enable(&mdev->napi[i]);
                napi_schedule(&mdev->napi[i]);
        }
        napi_enable(&mdev->tx_napi);
        napi_schedule(&mdev->tx_napi);
+       local_bh_enable();
 
        /* restore previous ds setting */
        if (!pm->ds_enable)