diff options
-rw-r--r-- | drivers/net/netconsole.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 63ffbdfe36c..dfffe8d8d69 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -626,6 +626,7 @@ static int netconsole_netdev_event(struct notifier_block *this, goto done; spin_lock_irqsave(&target_list_lock, flags); +restart: list_for_each_entry(nt, &target_list, list) { netconsole_target_get(nt); if (nt->np.dev == dev) { @@ -637,21 +638,18 @@ static int netconsole_netdev_event(struct notifier_block *this, case NETDEV_JOIN: case NETDEV_UNREGISTER: /* + * we might sleep in __netpoll_cleanup() * rtnl_lock already held */ - if (nt->np.dev) { - spin_unlock_irqrestore( - &target_list_lock, - flags); - __netpoll_cleanup(&nt->np); - spin_lock_irqsave(&target_list_lock, - flags); - dev_put(nt->np.dev); - nt->np.dev = NULL; - } + spin_unlock_irqrestore(&target_list_lock, flags); + __netpoll_cleanup(&nt->np); + spin_lock_irqsave(&target_list_lock, flags); + dev_put(nt->np.dev); + nt->np.dev = NULL; nt->enabled = 0; stopped = true; - break; + netconsole_target_put(nt); + goto restart; } } netconsole_target_put(nt); |