[NET]: Fix race condition about network device name allocation.

Kenji Kaneshige found this race between device removal and
registration. On unregister it is possible for the old device to
exist, because sysfs file is still open. A new device with 'eth%d'
will select the same name, but sysfs kobject register will fial.

The following changes the shutdown order slightly. It hold a removes
the sysfs entries earlier (on unregister_netdevice), but holds a
kobject reference. Then when todo runs the actual last put free
happens.

Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Stephen Hemminger and committed by David S. Miller 9093bbb2 d8cf2728

+13 -5
+6 -4
net/core/dev.c
··· 3314 continue; 3315 } 3316 3317 - netdev_unregister_sysfs(dev); 3318 dev->reg_state = NETREG_UNREGISTERED; 3319 3320 netdev_wait_allrefs(dev); ··· 3324 BUG_TRAP(!dev->ip6_ptr); 3325 BUG_TRAP(!dev->dn_ptr); 3326 3327 - /* It must be the very last action, 3328 - * after this 'dev' may point to freed up memory. 3329 - */ 3330 if (dev->destructor) 3331 dev->destructor(dev); 3332 } 3333 3334 out: ··· 3478 3479 /* Notifier chain MUST detach us from master device. */ 3480 BUG_TRAP(!dev->master); 3481 3482 /* Finish processing unregister after unlock */ 3483 net_set_todo(dev);
··· 3314 continue; 3315 } 3316 3317 dev->reg_state = NETREG_UNREGISTERED; 3318 3319 netdev_wait_allrefs(dev); ··· 3325 BUG_TRAP(!dev->ip6_ptr); 3326 BUG_TRAP(!dev->dn_ptr); 3327 3328 if (dev->destructor) 3329 dev->destructor(dev); 3330 + 3331 + /* Free network device */ 3332 + kobject_put(&dev->dev.kobj); 3333 } 3334 3335 out: ··· 3479 3480 /* Notifier chain MUST detach us from master device. */ 3481 BUG_TRAP(!dev->master); 3482 + 3483 + /* Remove entries from sysfs */ 3484 + netdev_unregister_sysfs(dev); 3485 3486 /* Finish processing unregister after unlock */ 3487 net_set_todo(dev);
+7 -1
net/core/net-sysfs.c
··· 456 #endif 457 }; 458 459 void netdev_unregister_sysfs(struct net_device * net) 460 { 461 - device_del(&(net->dev)); 462 } 463 464 /* Create sysfs entries for network device. */
··· 456 #endif 457 }; 458 459 + /* Delete sysfs entries but hold kobject reference until after all 460 + * netdev references are gone. 461 + */ 462 void netdev_unregister_sysfs(struct net_device * net) 463 { 464 + struct device *dev = &(net->dev); 465 + 466 + kobject_get(&dev->kobj); 467 + device_del(dev); 468 } 469 470 /* Create sysfs entries for network device. */