The qede driver contains a deadlock that freezes the entire Linux network control plane. A TX timeout or other recovery trigger invokes qede_recovery_handler(), which holds the driver's internal qede_lock while calling udp_tunnel_nic_reset_ntf(). This kernel function synchronously invokes a driver callback (qede_udp_tunnel_sync) that attempts to acquire qede_lock again—but the lock is non-recursive and already held by the same task. Every consumer of rtnl_lock then deadlocks: ovs-vswitchd, lldpad, IPv6 addrconf, sshd, and ip commands all freeze. The node continues responding to ping, making this far more dangerous than a simple crash—the system appears alive while the entire network control surface is frozen.
The fix is structurally revealing. It removes qede_lock() entirely from the recovery path, noting it was the only user. This is not a conservative synchronization improvement—it exposes that the lock was either protecting state that doesn't exist during recovery or protecting nothing at all. The inconsistency is telling: qede_open() correctly calls udp_tunnel_nic_reset_ntf() without holding qede_lock, but the recovery handler was written later under pressure and assumed extra locking was safer. The opposite was true.
The deeper problem is the udp_tunnel_nic interface itself, which requires callers to hold rtnl_lock while synchronously invoking driver callbacks that may attempt their own locking. This creates structural pressure toward exactly this deadlock in every driver using the interface. The fix corrects qede but does not fix the API contract that makes the error reproducible.
If you run qede in production, treat any TX timeout as a potential control-plane freeze until this is patched. Monitor for hung ip commands and ovs-vswitchd processes as leading indicators. The workaround is to have console access ready to recover the node, since the deadlock is unrecoverable from the network management interface.