Commit ecf0b2b8 authored by Leon Yen's avatar Leon Yen Committed by Felix Fietkau

wifi: mt76: mt7921s: fix potential hung tasks during chip recovery

During chip recovery (e.g. chip reset), there is a possible situation that
kernel worker reset_work is holding the lock and waiting for kernel thread
stat_worker to be parked, while stat_worker is waiting for the release of
the same lock.
It causes a deadlock resulting in the dumping of hung tasks messages and
possible rebooting of the device.

This patch prevents the execution of stat_worker during the chip recovery.
Signed-off-by: default avatarLeon Yen <leon.yen@mediatek.com>
Signed-off-by: default avatarMing Yen Hsieh <MingYen.Hsieh@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent 4a40fcbf
...@@ -663,6 +663,7 @@ void mt7921_mac_reset_work(struct work_struct *work) ...@@ -663,6 +663,7 @@ void mt7921_mac_reset_work(struct work_struct *work)
int i, ret; int i, ret;
dev_dbg(dev->mt76.dev, "chip reset\n"); dev_dbg(dev->mt76.dev, "chip reset\n");
set_bit(MT76_RESET, &dev->mphy.state);
dev->hw_full_reset = true; dev->hw_full_reset = true;
ieee80211_stop_queues(hw); ieee80211_stop_queues(hw);
...@@ -691,6 +692,7 @@ void mt7921_mac_reset_work(struct work_struct *work) ...@@ -691,6 +692,7 @@ void mt7921_mac_reset_work(struct work_struct *work)
} }
dev->hw_full_reset = false; dev->hw_full_reset = false;
clear_bit(MT76_RESET, &dev->mphy.state);
pm->suspended = false; pm->suspended = false;
ieee80211_wake_queues(hw); ieee80211_wake_queues(hw);
ieee80211_iterate_active_interfaces(hw, ieee80211_iterate_active_interfaces(hw,
......
...@@ -64,7 +64,6 @@ int mt7921e_mac_reset(struct mt792x_dev *dev) ...@@ -64,7 +64,6 @@ int mt7921e_mac_reset(struct mt792x_dev *dev)
mt76_wr(dev, dev->irq_map->host_irq_enable, 0); mt76_wr(dev, dev->irq_map->host_irq_enable, 0);
mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0); mt76_wr(dev, MT_PCIE_MAC_INT_ENABLE, 0x0);
set_bit(MT76_RESET, &dev->mphy.state);
set_bit(MT76_MCU_RESET, &dev->mphy.state); set_bit(MT76_MCU_RESET, &dev->mphy.state);
wake_up(&dev->mt76.mcu.wait); wake_up(&dev->mt76.mcu.wait);
skb_queue_purge(&dev->mt76.mcu.res_q); skb_queue_purge(&dev->mt76.mcu.res_q);
...@@ -115,7 +114,6 @@ int mt7921e_mac_reset(struct mt792x_dev *dev) ...@@ -115,7 +114,6 @@ int mt7921e_mac_reset(struct mt792x_dev *dev)
err = __mt7921_start(&dev->phy); err = __mt7921_start(&dev->phy);
out: out:
clear_bit(MT76_RESET, &dev->mphy.state);
local_bh_disable(); local_bh_disable();
napi_enable(&dev->mt76.tx_napi); napi_enable(&dev->mt76.tx_napi);
......
...@@ -98,7 +98,6 @@ int mt7921s_mac_reset(struct mt792x_dev *dev) ...@@ -98,7 +98,6 @@ int mt7921s_mac_reset(struct mt792x_dev *dev)
mt76_connac_free_pending_tx_skbs(&dev->pm, NULL); mt76_connac_free_pending_tx_skbs(&dev->pm, NULL);
mt76_txq_schedule_all(&dev->mphy); mt76_txq_schedule_all(&dev->mphy);
mt76_worker_disable(&dev->mt76.tx_worker); mt76_worker_disable(&dev->mt76.tx_worker);
set_bit(MT76_RESET, &dev->mphy.state);
set_bit(MT76_MCU_RESET, &dev->mphy.state); set_bit(MT76_MCU_RESET, &dev->mphy.state);
wake_up(&dev->mt76.mcu.wait); wake_up(&dev->mt76.mcu.wait);
skb_queue_purge(&dev->mt76.mcu.res_q); skb_queue_purge(&dev->mt76.mcu.res_q);
...@@ -135,7 +134,6 @@ int mt7921s_mac_reset(struct mt792x_dev *dev) ...@@ -135,7 +134,6 @@ int mt7921s_mac_reset(struct mt792x_dev *dev)
err = __mt7921_start(&dev->phy); err = __mt7921_start(&dev->phy);
out: out:
clear_bit(MT76_RESET, &dev->mphy.state);
mt76_worker_enable(&dev->mt76.tx_worker); mt76_worker_enable(&dev->mt76.tx_worker);
......
...@@ -499,7 +499,8 @@ static void mt76s_tx_status_data(struct mt76_worker *worker) ...@@ -499,7 +499,8 @@ static void mt76s_tx_status_data(struct mt76_worker *worker)
dev = container_of(sdio, struct mt76_dev, sdio); dev = container_of(sdio, struct mt76_dev, sdio);
while (true) { while (true) {
if (test_bit(MT76_REMOVED, &dev->phy.state)) if (test_bit(MT76_RESET, &dev->phy.state) ||
test_bit(MT76_REMOVED, &dev->phy.state))
break; break;
if (!dev->drv->tx_status_data(dev, &update)) if (!dev->drv->tx_status_data(dev, &update))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment