Date: Sun, 14 Jun 2026 22:32:28 +0000 From: Bjoern A. Zeeb <bz@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: 009d92b25f7c - main - mt76: mt7921: prevent PM from scheduling another delayed work on detach Message-ID: <6a2f2bfc.434e1.464e6810@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=009d92b25f7c2d6ddf3fb4202d0a6a4612a716f1 commit 009d92b25f7c2d6ddf3fb4202d0a6a4612a716f1 Author: Bjoern A. Zeeb <bz@FreeBSD.org> AuthorDate: 2026-06-14 16:37:10 +0000 Commit: Bjoern A. Zeeb <bz@FreeBSD.org> CommitDate: 2026-06-14 22:31:38 +0000 mt76: mt7921: prevent PM from scheduling another delayed work on detach Amongst others mt76_connac_pm_unref() is calling mt76_connac_power_save_sched() which will (normaly) re-schedule the pm_work. In various parts we also cancel that work, also during PCI detach ("shutdown", "remove" in LinuxKPI terms). However we also keep calling mt76_connac_pm_unref() in the detach path and thus we get to a point where we re-scheduled the work but then the device goes away. At that point LinuxKPI delayed work has a callput pending which is embedded in the work structure (pm_work). The moment we free the device that structure and callout is gone but the callout is still on the list and once that list is walked we panic. Simply prevent mt76_connac_power_save_sched() from getting to the point of possibly re-scheduling the pm_work by setting pm->enable to false in the beginning of the detach path. The are likely more paths which will need the same treatment as the code is by far anything from "symmetric" (that is the attach path is highly bus independent while the detach path is implemented per-bus). Also other chipsets share the same "logical paths" with their own names, so they will need this too once we get to them. Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/contrib/dev/mediatek/mt76/mt7921/pci.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sys/contrib/dev/mediatek/mt76/mt7921/pci.c b/sys/contrib/dev/mediatek/mt76/mt7921/pci.c index 46b59c4d0390..b70335aba6bf 100644 --- a/sys/contrib/dev/mediatek/mt76/mt7921/pci.c +++ b/sys/contrib/dev/mediatek/mt76/mt7921/pci.c @@ -51,6 +51,17 @@ static void mt7921e_unregister_device(struct mt792x_dev *dev) if (dev->phy.chip_cap & MT792x_CHIP_CAP_WF_RF_PIN_CTRL_EVT_EN) wiphy_rfkill_stop_polling(hw->wiphy); +#if defined(__FreeBSD__) + /* + * Prevent scheduling ps_work again in mt76_connac_power_save_sched(). + * Otherwise upon shutdown we may have delayed work pending, which on + * FreeBSD means there is a callout running, but the ps_work will be + * freed along with the mt792x_dev and so there is a callout on a list + * which no longer exists. + */ + pm->enable = false; +#endif + cancel_work_sync(&dev->init_work); mt76_unregister_device(&dev->mt76); mt76_for_each_q_rx(&dev->mt76, i)home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a2f2bfc.434e1.464e6810>
