diff options
-rw-r--r-- | net/core/dev.c | 10 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 8 |
2 files changed, 13 insertions, 5 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 2a587b86162..3c3d383d24c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3138,7 +3138,6 @@ void netdev_run_todo(void) continue; } - netdev_unregister_sysfs(dev); dev->reg_state = NETREG_UNREGISTERED; netdev_wait_allrefs(dev); @@ -3149,11 +3148,11 @@ void netdev_run_todo(void) BUG_TRAP(!dev->ip6_ptr); BUG_TRAP(!dev->dn_ptr); - /* It must be the very last action, - * after this 'dev' may point to freed up memory. - */ if (dev->destructor) dev->destructor(dev); + + /* Free network device */ + kobject_put(&dev->class_dev.kobj); } out: @@ -3310,6 +3309,9 @@ int unregister_netdevice(struct net_device *dev) /* Notifier chain MUST detach us from master device. */ BUG_TRAP(!dev->master); + /* Remove entries from sysfs */ + netdev_unregister_sysfs(dev); + /* Finish processing unregister after unlock */ net_set_todo(dev); diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index f47f319bb7d..c60fe3b86bb 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -440,9 +440,15 @@ static struct class net_class = { #endif }; +/* Delete sysfs entries but hold kobject reference until after all + * netdev references are gone. + */ void netdev_unregister_sysfs(struct net_device * net) { - class_device_del(&(net->class_dev)); + struct class_device *dev = &(net->class_dev); + + kobject_get(&dev->kobj); + class_device_del(dev); } /* Create sysfs entries for network device. */ |