forked from mirrors/linux
		
	mt76: disable BH around napi_schedule() calls
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>
This commit is contained in:
		
							parent
							
								
									abe3f3da67
								
							
						
					
					
						commit
						970be1dff2
					
				
					 9 changed files with 30 additions and 4 deletions
				
			
		| 
						 | 
					@ -1471,17 +1471,20 @@ static void mt7603_mac_watchdog_reset(struct mt7603_dev *dev)
 | 
				
			||||||
	mutex_unlock(&dev->mt76.mutex);
 | 
						mutex_unlock(&dev->mt76.mutex);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mt76_worker_enable(&dev->mt76.tx_worker);
 | 
						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);
 | 
						tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
 | 
				
			||||||
	mt7603_beacon_set_timer(dev, -1, beacon_int);
 | 
						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_enable(&dev->mt76.napi[0]);
 | 
				
			||||||
	napi_schedule(&dev->mt76.napi[0]);
 | 
						napi_schedule(&dev->mt76.napi[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	napi_enable(&dev->mt76.napi[1]);
 | 
						napi_enable(&dev->mt76.napi[1]);
 | 
				
			||||||
	napi_schedule(&dev->mt76.napi[1]);
 | 
						napi_schedule(&dev->mt76.napi[1]);
 | 
				
			||||||
 | 
						local_bh_enable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ieee80211_wake_queues(dev->mt76.hw);
 | 
						ieee80211_wake_queues(dev->mt76.hw);
 | 
				
			||||||
	mt76_txq_schedule_all(&dev->mphy);
 | 
						mt76_txq_schedule_all(&dev->mphy);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -164,12 +164,14 @@ static int mt7615_pci_resume(struct pci_dev *pdev)
 | 
				
			||||||
		dev_err(mdev->dev, "PDMA engine must be reinitialized\n");
 | 
							dev_err(mdev->dev, "PDMA engine must be reinitialized\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mt76_worker_enable(&mdev->tx_worker);
 | 
						mt76_worker_enable(&mdev->tx_worker);
 | 
				
			||||||
 | 
						local_bh_disable();
 | 
				
			||||||
	mt76_for_each_q_rx(mdev, i) {
 | 
						mt76_for_each_q_rx(mdev, i) {
 | 
				
			||||||
		napi_enable(&mdev->napi[i]);
 | 
							napi_enable(&mdev->napi[i]);
 | 
				
			||||||
		napi_schedule(&mdev->napi[i]);
 | 
							napi_schedule(&mdev->napi[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	napi_enable(&mdev->tx_napi);
 | 
						napi_enable(&mdev->tx_napi);
 | 
				
			||||||
	napi_schedule(&mdev->tx_napi);
 | 
						napi_schedule(&mdev->tx_napi);
 | 
				
			||||||
 | 
						local_bh_enable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) &&
 | 
						if (!test_bit(MT76_STATE_SUSPEND, &dev->mphy.state) &&
 | 
				
			||||||
	    mt7615_firmware_offload(dev))
 | 
						    mt7615_firmware_offload(dev))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -326,6 +326,8 @@ void mt7615_mac_reset_work(struct work_struct *work)
 | 
				
			||||||
		clear_bit(MT76_RESET, &phy2->mt76->state);
 | 
							clear_bit(MT76_RESET, &phy2->mt76->state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mt76_worker_enable(&dev->mt76.tx_worker);
 | 
						mt76_worker_enable(&dev->mt76.tx_worker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local_bh_disable();
 | 
				
			||||||
	napi_enable(&dev->mt76.tx_napi);
 | 
						napi_enable(&dev->mt76.tx_napi);
 | 
				
			||||||
	napi_schedule(&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_enable(&dev->mt76.napi[1]);
 | 
				
			||||||
	napi_schedule(&dev->mt76.napi[1]);
 | 
						napi_schedule(&dev->mt76.napi[1]);
 | 
				
			||||||
 | 
						local_bh_enable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ieee80211_wake_queues(mt76_hw(dev));
 | 
						ieee80211_wake_queues(mt76_hw(dev));
 | 
				
			||||||
	if (ext_phy)
 | 
						if (ext_phy)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -276,6 +276,7 @@ static int mt76x0e_resume(struct pci_dev *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mt76_worker_enable(&mdev->tx_worker);
 | 
						mt76_worker_enable(&mdev->tx_worker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local_bh_disable();
 | 
				
			||||||
	mt76_for_each_q_rx(mdev, i) {
 | 
						mt76_for_each_q_rx(mdev, i) {
 | 
				
			||||||
		mt76_queue_rx_reset(dev, i);
 | 
							mt76_queue_rx_reset(dev, i);
 | 
				
			||||||
		napi_enable(&mdev->napi[i]);
 | 
							napi_enable(&mdev->napi[i]);
 | 
				
			||||||
| 
						 | 
					@ -284,6 +285,7 @@ static int mt76x0e_resume(struct pci_dev *pdev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	napi_enable(&mdev->tx_napi);
 | 
						napi_enable(&mdev->tx_napi);
 | 
				
			||||||
	napi_schedule(&mdev->tx_napi);
 | 
						napi_schedule(&mdev->tx_napi);
 | 
				
			||||||
 | 
						local_bh_enable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return mt76x0e_init_hardware(dev, true);
 | 
						return mt76x0e_init_hardware(dev, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -491,15 +491,17 @@ static void mt76x02_watchdog_reset(struct mt76x02_dev *dev)
 | 
				
			||||||
	clear_bit(MT76_RESET, &dev->mphy.state);
 | 
						clear_bit(MT76_RESET, &dev->mphy.state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mt76_worker_enable(&dev->mt76.tx_worker);
 | 
						mt76_worker_enable(&dev->mt76.tx_worker);
 | 
				
			||||||
 | 
						tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local_bh_disable();
 | 
				
			||||||
	napi_enable(&dev->mt76.tx_napi);
 | 
						napi_enable(&dev->mt76.tx_napi);
 | 
				
			||||||
	napi_schedule(&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) {
 | 
						mt76_for_each_q_rx(&dev->mt76, i) {
 | 
				
			||||||
		napi_enable(&dev->mt76.napi[i]);
 | 
							napi_enable(&dev->mt76.napi[i]);
 | 
				
			||||||
		napi_schedule(&dev->mt76.napi[i]);
 | 
							napi_schedule(&dev->mt76.napi[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						local_bh_enable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (restart) {
 | 
						if (restart) {
 | 
				
			||||||
		set_bit(MT76_RESTART, &dev->mphy.state);
 | 
							set_bit(MT76_RESTART, &dev->mphy.state);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,12 +149,15 @@ mt76x2e_resume(struct pci_dev *pdev)
 | 
				
			||||||
	pci_restore_state(pdev);
 | 
						pci_restore_state(pdev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mt76_worker_enable(&mdev->tx_worker);
 | 
						mt76_worker_enable(&mdev->tx_worker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local_bh_disable();
 | 
				
			||||||
	mt76_for_each_q_rx(mdev, i) {
 | 
						mt76_for_each_q_rx(mdev, i) {
 | 
				
			||||||
		napi_enable(&mdev->napi[i]);
 | 
							napi_enable(&mdev->napi[i]);
 | 
				
			||||||
		napi_schedule(&mdev->napi[i]);
 | 
							napi_schedule(&mdev->napi[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	napi_enable(&mdev->tx_napi);
 | 
						napi_enable(&mdev->tx_napi);
 | 
				
			||||||
	napi_schedule(&mdev->tx_napi);
 | 
						napi_schedule(&mdev->tx_napi);
 | 
				
			||||||
 | 
						local_bh_enable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return mt76x2_resume_device(dev);
 | 
						return mt76x2_resume_device(dev);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1837,6 +1837,7 @@ void mt7915_mac_reset_work(struct work_struct *work)
 | 
				
			||||||
	if (phy2)
 | 
						if (phy2)
 | 
				
			||||||
		clear_bit(MT76_RESET, &phy2->mt76->state);
 | 
							clear_bit(MT76_RESET, &phy2->mt76->state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local_bh_disable();
 | 
				
			||||||
	napi_enable(&dev->mt76.napi[0]);
 | 
						napi_enable(&dev->mt76.napi[0]);
 | 
				
			||||||
	napi_schedule(&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_enable(&dev->mt76.napi[2]);
 | 
				
			||||||
	napi_schedule(&dev->mt76.napi[2]);
 | 
						napi_schedule(&dev->mt76.napi[2]);
 | 
				
			||||||
 | 
						local_bh_enable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tasklet_schedule(&dev->irq_tasklet);
 | 
						tasklet_schedule(&dev->irq_tasklet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
 | 
						mt76_wr(dev, MT_MCU_INT_EVENT, MT_MCU_INT_EVENT_RESET_DONE);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1390,10 +1390,12 @@ mt7921_mac_reset(struct mt7921_dev *dev)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mt7921_wpdma_reset(dev, true);
 | 
						mt7921_wpdma_reset(dev, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local_bh_disable();
 | 
				
			||||||
	mt76_for_each_q_rx(&dev->mt76, i) {
 | 
						mt76_for_each_q_rx(&dev->mt76, i) {
 | 
				
			||||||
		napi_enable(&dev->mt76.napi[i]);
 | 
							napi_enable(&dev->mt76.napi[i]);
 | 
				
			||||||
		napi_schedule(&dev->mt76.napi[i]);
 | 
							napi_schedule(&dev->mt76.napi[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						local_bh_enable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	clear_bit(MT76_MCU_RESET, &dev->mphy.state);
 | 
						clear_bit(MT76_MCU_RESET, &dev->mphy.state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1418,8 +1420,11 @@ mt7921_mac_reset(struct mt7921_dev *dev)
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	clear_bit(MT76_RESET, &dev->mphy.state);
 | 
						clear_bit(MT76_RESET, &dev->mphy.state);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local_bh_disable();
 | 
				
			||||||
	napi_enable(&dev->mt76.tx_napi);
 | 
						napi_enable(&dev->mt76.tx_napi);
 | 
				
			||||||
	napi_schedule(&dev->mt76.tx_napi);
 | 
						napi_schedule(&dev->mt76.tx_napi);
 | 
				
			||||||
 | 
						local_bh_enable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mt76_worker_enable(&dev->mt76.tx_worker);
 | 
						mt76_worker_enable(&dev->mt76.tx_worker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
							 MT_WFDMA0_GLO_CFG_TX_DMA_EN | MT_WFDMA0_GLO_CFG_RX_DMA_EN);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mt76_worker_enable(&mdev->tx_worker);
 | 
						mt76_worker_enable(&mdev->tx_worker);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local_bh_disable();
 | 
				
			||||||
	mt76_for_each_q_rx(mdev, i) {
 | 
						mt76_for_each_q_rx(mdev, i) {
 | 
				
			||||||
		napi_enable(&mdev->napi[i]);
 | 
							napi_enable(&mdev->napi[i]);
 | 
				
			||||||
		napi_schedule(&mdev->napi[i]);
 | 
							napi_schedule(&mdev->napi[i]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	napi_enable(&mdev->tx_napi);
 | 
						napi_enable(&mdev->tx_napi);
 | 
				
			||||||
	napi_schedule(&mdev->tx_napi);
 | 
						napi_schedule(&mdev->tx_napi);
 | 
				
			||||||
 | 
						local_bh_enable();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* restore previous ds setting */
 | 
						/* restore previous ds setting */
 | 
				
			||||||
	if (!pm->ds_enable)
 | 
						if (!pm->ds_enable)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue