From 3f769c7c981af1fa99aa05c960b67aab2f2e6047 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 7 Oct 2008 15:50:03 -0700 Subject: [PATCH] --- yaml --- r: 110235 b: refs/heads/master c: 58ec3b4db9eb5a28e3aec5f407a54e28f7039c19 h: refs/heads/master i: 110233: 31730940a97b2d0e4af173b896e7acf1f4fd5aae 110231: bf78cb420f19c3a98f23925903a01c495d5f2d97 v: v3 --- [refs] | 2 +- trunk/net/core/dev.c | 27 ++++++--------------------- trunk/net/core/rtnetlink.c | 2 +- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/[refs] b/[refs] index 958ef84f671e..039aed5be3d1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 742201e7baf66c64995fdd033d706220e6208fab +refs/heads/master: 58ec3b4db9eb5a28e3aec5f407a54e28f7039c19 diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index fd992c0f2717..0ae08d3f57e7 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -3812,14 +3812,11 @@ static int dev_new_index(struct net *net) } /* Delayed registration/unregisteration */ -static DEFINE_SPINLOCK(net_todo_list_lock); static LIST_HEAD(net_todo_list); static void net_set_todo(struct net_device *dev) { - spin_lock(&net_todo_list_lock); list_add_tail(&dev->todo_list, &net_todo_list); - spin_unlock(&net_todo_list_lock); } static void rollback_registered(struct net_device *dev) @@ -4146,33 +4143,24 @@ static void netdev_wait_allrefs(struct net_device *dev) * free_netdev(y1); * free_netdev(y2); * - * We are invoked by rtnl_unlock() after it drops the semaphore. + * We are invoked by rtnl_unlock(). * This allows us to deal with problems: * 1) We can delete sysfs objects which invoke hotplug * without deadlocking with linkwatch via keventd. * 2) Since we run with the RTNL semaphore not held, we can sleep * safely in order to wait for the netdev refcnt to drop to zero. + * + * We must not return until all unregister events added during + * the interval the lock was held have been completed. */ -static DEFINE_MUTEX(net_todo_run_mutex); void netdev_run_todo(void) { struct list_head list; - /* Need to guard against multiple cpu's getting out of order. */ - mutex_lock(&net_todo_run_mutex); - - /* Not safe to do outside the semaphore. We must not return - * until all unregister events invoked by the local processor - * have been completed (either by this todo run, or one on - * another cpu). - */ - if (list_empty(&net_todo_list)) - goto out; - /* Snapshot list, allow later requests */ - spin_lock(&net_todo_list_lock); list_replace_init(&net_todo_list, &list); - spin_unlock(&net_todo_list_lock); + + __rtnl_unlock(); while (!list_empty(&list)) { struct net_device *dev @@ -4204,9 +4192,6 @@ void netdev_run_todo(void) /* Free network device */ kobject_put(&dev->dev.kobj); } - -out: - mutex_unlock(&net_todo_run_mutex); } static struct net_device_stats *internal_stats(struct net_device *dev) diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index 71edb8b36341..d6381c2a4693 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -73,7 +73,7 @@ void __rtnl_unlock(void) void rtnl_unlock(void) { - mutex_unlock(&rtnl_mutex); + /* This fellow will unlock it for us. */ netdev_run_todo(); }