When unplugging cable with lockdep enabled it triggers following: ====================================================== WARNING: possible circular locking dependency detected 6.18.0-rc4+ #1636 Tainted: G S ------------------------------------------------------ kworker/u56:2/416 is trying to acquire lock: ffff88818642c8a8 ((work_completion)(&ring->work)){+.+.}-{0:0}, at: __flush_work+0x562/0xde0 but task is already holding lock: ffff888184b30fa8 (&net->connection_lock){+.+.}-{4:4}, at: tbnet_tear_down+0x110/0x6f0 [thunderbolt_net] We actually don't need to net->hold the connection_lock any more than necessary to figure out if the connection is up or not, and can return early if it is not. Signed-off-by: Mika Westerberg --- drivers/net/thunderbolt/main.c | 59 +++++++++++++++++----------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/drivers/net/thunderbolt/main.c b/drivers/net/thunderbolt/main.c index 631af237998d..d8fcf18fc55c 100644 --- a/drivers/net/thunderbolt/main.c +++ b/drivers/net/thunderbolt/main.c @@ -372,48 +372,47 @@ static void tbnet_free_buffers(struct tbnet_ring *ring) static void tbnet_tear_down(struct tbnet *net, bool send_logout) { + int ret, retries = TBNET_LOGOUT_RETRIES; + netif_carrier_off(net->dev); netif_stop_queue(net->dev); stop_login(net); mutex_lock(&net->connection_lock); + if (!net->login_sent || !net->login_received) { + mutex_unlock(&net->connection_lock); + return; + } + net->login_sent = false; + net->login_received = false; + mutex_unlock(&net->connection_lock); - if (net->login_sent && net->login_received) { - int ret, retries = TBNET_LOGOUT_RETRIES; + while (send_logout && retries-- > 0) { + netdev_dbg(net->dev, "sending logout request %u\n", + retries); + ret = tbnet_logout_request(net); + if (ret != -ETIMEDOUT) + break; + } - while (send_logout && retries-- > 0) { - netdev_dbg(net->dev, "sending logout request %u\n", - retries); - ret = tbnet_logout_request(net); - if (ret != -ETIMEDOUT) - break; - } + tb_ring_stop(net->rx_ring.ring); + tb_ring_stop(net->tx_ring.ring); + tbnet_free_buffers(&net->rx_ring); + tbnet_free_buffers(&net->tx_ring); - tb_ring_stop(net->rx_ring.ring); - tb_ring_stop(net->tx_ring.ring); - tbnet_free_buffers(&net->rx_ring); - tbnet_free_buffers(&net->tx_ring); - - ret = tb_xdomain_disable_paths(net->xd, - net->local_transmit_path, - net->tx_ring.ring->hop, - net->remote_transmit_path, - net->rx_ring.ring->hop); - if (ret) - netdev_warn(net->dev, "failed to disable DMA paths\n"); - - tb_xdomain_release_in_hopid(net->xd, net->remote_transmit_path); - net->remote_transmit_path = 0; - } + ret = tb_xdomain_disable_paths(net->xd, + net->local_transmit_path, + net->tx_ring.ring->hop, + net->remote_transmit_path, + net->rx_ring.ring->hop); + if (ret) + netdev_warn(net->dev, "failed to disable DMA paths\n"); - net->login_retries = 0; - net->login_sent = false; - net->login_received = false; + tb_xdomain_release_in_hopid(net->xd, net->remote_transmit_path); + net->remote_transmit_path = 0; netdev_dbg(net->dev, "network traffic stopped\n"); - - mutex_unlock(&net->connection_lock); } static int tbnet_handle_packet(const void *buf, size_t size, void *data) -- 2.50.1