On 10.10.2023 09:35:19, Marc Kleine-Budde wrote:
The dm9000 takes the db->lock spin lock in dm9000_timeout() and calls into dm9000_init_dm9000(). For the DM9000B the PHY is reset with dm9000_phy_write(). That function again takes the db->lock spin lock, which results in a deadlock. For reference the backtrace:
| [<c0425050>] (rt_spin_lock_slowlock_locked) from [<c0425100>] (rt_spin_lock_slowlock+0x60/0xc4) | [<c0425100>] (rt_spin_lock_slowlock) from [<c02e1174>] (dm9000_phy_write+0x2c/0x1a4) | [<c02e1174>] (dm9000_phy_write) from [<c02e16b0>] (dm9000_init_dm9000+0x288/0x2a4) | [<c02e16b0>] (dm9000_init_dm9000) from [<c02e1724>] (dm9000_timeout+0x58/0xd4) | [<c02e1724>] (dm9000_timeout) from [<c036f298>] (dev_watchdog+0x258/0x2a8) | [<c036f298>] (dev_watchdog) from [<c0068168>] (call_timer_fn+0x20/0x88) | [<c0068168>] (call_timer_fn) from [<c00687c8>] (expire_timers+0xf0/0x194) | [<c00687c8>] (expire_timers) from [<c0068920>] (run_timer_softirq+0xb4/0x25c) | [<c0068920>] (run_timer_softirq) from [<c0021a30>] (do_current_softirqs+0x16c/0x228) | [<c0021a30>] (do_current_softirqs) from [<c0021b14>] (run_ksoftirqd+0x28/0x4c) | [<c0021b14>] (run_ksoftirqd) from [<c0040488>] (smpboot_thread_fn+0x278/0x290) | [<c0040488>] (smpboot_thread_fn) from [<c003c28c>] (kthread+0x124/0x164) | [<c003c28c>] (kthread) from [<c00090f0>] (ret_from_fork+0x14/0x24)
To workaround similar problem (take mutex inside spin lock ) , a "in_timeout" variable was added in 582379839bbd ("dm9000: avoid sleeping in dm9000_timeout callback"). Use this variable and not take the spin lock inside dm9000_phy_write() if in_timeout is true.
Cc: stable@vger.kernel.org Signed-off-by: Marc Kleine-Budde mkl@pengutronix.de
Fixes: a1365275e745 ("[PATCH] DM9000 network driver")
regards, Marc