Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9093bbb2d96d0184f037cea9b4e952a44ebe7c32
Commit:     9093bbb2d96d0184f037cea9b4e952a44ebe7c32
Parent:     d8cf27287ac7fb5cbfcc4139917a997c39d841ca
Author:     Stephen Hemminger <[EMAIL PROTECTED]>
AuthorDate: Sat May 19 15:39:25 2007 -0700
Committer:  David S. Miller <[EMAIL PROTECTED]>
CommitDate: Sat May 19 15:39:25 2007 -0700

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: David S. Miller <[EMAIL PROTECTED]>
---
 net/core/dev.c       |   10 ++++++----
 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 f2b6111..5a7f20f 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3314,7 +3314,6 @@ void netdev_run_todo(void)
                        continue;
                }
 
-               netdev_unregister_sysfs(dev);
                dev->reg_state = NETREG_UNREGISTERED;
 
                netdev_wait_allrefs(dev);
@@ -3325,11 +3324,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->dev.kobj);
        }
 
 out:
@@ -3480,6 +3479,9 @@ void 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 b21307b..5c19b06 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -456,9 +456,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)
 {
-       device_del(&(net->dev));
+       struct device *dev = &(net->dev);
+
+       kobject_get(&dev->kobj);
+       device_del(dev);
 }
 
 /* Create sysfs entries for network device. */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to