|
@@ -671,6 +671,7 @@ static int netconsole_netdev_event(struct notifier_block *this,
|
|
goto done;
|
|
goto done;
|
|
|
|
|
|
spin_lock_irqsave(&target_list_lock, flags);
|
|
spin_lock_irqsave(&target_list_lock, flags);
|
|
|
|
+restart:
|
|
list_for_each_entry(nt, &target_list, list) {
|
|
list_for_each_entry(nt, &target_list, list) {
|
|
netconsole_target_get(nt);
|
|
netconsole_target_get(nt);
|
|
if (nt->np.dev == dev) {
|
|
if (nt->np.dev == dev) {
|
|
@@ -683,9 +684,16 @@ static int netconsole_netdev_event(struct notifier_block *this,
|
|
* rtnl_lock already held
|
|
* rtnl_lock already held
|
|
*/
|
|
*/
|
|
if (nt->np.dev) {
|
|
if (nt->np.dev) {
|
|
|
|
+ spin_unlock_irqrestore(
|
|
|
|
+ &target_list_lock,
|
|
|
|
+ flags);
|
|
__netpoll_cleanup(&nt->np);
|
|
__netpoll_cleanup(&nt->np);
|
|
|
|
+ spin_lock_irqsave(&target_list_lock,
|
|
|
|
+ flags);
|
|
dev_put(nt->np.dev);
|
|
dev_put(nt->np.dev);
|
|
nt->np.dev = NULL;
|
|
nt->np.dev = NULL;
|
|
|
|
+ netconsole_target_put(nt);
|
|
|
|
+ goto restart;
|
|
}
|
|
}
|
|
/* Fall through */
|
|
/* Fall through */
|
|
case NETDEV_GOING_DOWN:
|
|
case NETDEV_GOING_DOWN:
|