diff options
author | David S. Miller <davem@davemloft.net> | 2008-10-08 17:56:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-10-08 17:56:41 -0400 |
commit | 4dd565134ece7e5d528d4c5288879310c54419e9 (patch) | |
tree | e08910d2d0feae0c030f8f01acc9b03eb760ad9a /net/core | |
parent | 071d7ab6649eb34a873a53e71635186e9117101d (diff) | |
parent | 69849375d6b13e94d08cdc94b49b11fbab454a0e (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/netdev.c
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 43 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 2 |
2 files changed, 17 insertions, 28 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 7091040e32ac..1408a083fe4e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2949,6 +2949,12 @@ int netdev_set_master(struct net_device *slave, struct net_device *master) | |||
2949 | return 0; | 2949 | return 0; |
2950 | } | 2950 | } |
2951 | 2951 | ||
2952 | static void dev_change_rx_flags(struct net_device *dev, int flags) | ||
2953 | { | ||
2954 | if (dev->flags & IFF_UP && dev->change_rx_flags) | ||
2955 | dev->change_rx_flags(dev, flags); | ||
2956 | } | ||
2957 | |||
2952 | static int __dev_set_promiscuity(struct net_device *dev, int inc) | 2958 | static int __dev_set_promiscuity(struct net_device *dev, int inc) |
2953 | { | 2959 | { |
2954 | unsigned short old_flags = dev->flags; | 2960 | unsigned short old_flags = dev->flags; |
@@ -2986,8 +2992,7 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc) | |||
2986 | current->uid, current->gid, | 2992 | current->uid, current->gid, |
2987 | audit_get_sessionid(current)); | 2993 | audit_get_sessionid(current)); |
2988 | 2994 | ||
2989 | if (dev->change_rx_flags) | 2995 | dev_change_rx_flags(dev, IFF_PROMISC); |
2990 | dev->change_rx_flags(dev, IFF_PROMISC); | ||
2991 | } | 2996 | } |
2992 | return 0; | 2997 | return 0; |
2993 | } | 2998 | } |
@@ -3053,8 +3058,7 @@ int dev_set_allmulti(struct net_device *dev, int inc) | |||
3053 | } | 3058 | } |
3054 | } | 3059 | } |
3055 | if (dev->flags ^ old_flags) { | 3060 | if (dev->flags ^ old_flags) { |
3056 | if (dev->change_rx_flags) | 3061 | dev_change_rx_flags(dev, IFF_ALLMULTI); |
3057 | dev->change_rx_flags(dev, IFF_ALLMULTI); | ||
3058 | dev_set_rx_mode(dev); | 3062 | dev_set_rx_mode(dev); |
3059 | } | 3063 | } |
3060 | return 0; | 3064 | return 0; |
@@ -3392,8 +3396,8 @@ int dev_change_flags(struct net_device *dev, unsigned flags) | |||
3392 | * Load in the correct multicast list now the flags have changed. | 3396 | * Load in the correct multicast list now the flags have changed. |
3393 | */ | 3397 | */ |
3394 | 3398 | ||
3395 | if (dev->change_rx_flags && (old_flags ^ flags) & IFF_MULTICAST) | 3399 | if ((old_flags ^ flags) & IFF_MULTICAST) |
3396 | dev->change_rx_flags(dev, IFF_MULTICAST); | 3400 | dev_change_rx_flags(dev, IFF_MULTICAST); |
3397 | 3401 | ||
3398 | dev_set_rx_mode(dev); | 3402 | dev_set_rx_mode(dev); |
3399 | 3403 | ||
@@ -3867,14 +3871,11 @@ static int dev_new_index(struct net *net) | |||
3867 | } | 3871 | } |
3868 | 3872 | ||
3869 | /* Delayed registration/unregisteration */ | 3873 | /* Delayed registration/unregisteration */ |
3870 | static DEFINE_SPINLOCK(net_todo_list_lock); | ||
3871 | static LIST_HEAD(net_todo_list); | 3874 | static LIST_HEAD(net_todo_list); |
3872 | 3875 | ||
3873 | static void net_set_todo(struct net_device *dev) | 3876 | static void net_set_todo(struct net_device *dev) |
3874 | { | 3877 | { |
3875 | spin_lock(&net_todo_list_lock); | ||
3876 | list_add_tail(&dev->todo_list, &net_todo_list); | 3878 | list_add_tail(&dev->todo_list, &net_todo_list); |
3877 | spin_unlock(&net_todo_list_lock); | ||
3878 | } | 3879 | } |
3879 | 3880 | ||
3880 | static void rollback_registered(struct net_device *dev) | 3881 | static void rollback_registered(struct net_device *dev) |
@@ -4201,33 +4202,24 @@ static void netdev_wait_allrefs(struct net_device *dev) | |||
4201 | * free_netdev(y1); | 4202 | * free_netdev(y1); |
4202 | * free_netdev(y2); | 4203 | * free_netdev(y2); |
4203 | * | 4204 | * |
4204 | * We are invoked by rtnl_unlock() after it drops the semaphore. | 4205 | * We are invoked by rtnl_unlock(). |
4205 | * This allows us to deal with problems: | 4206 | * This allows us to deal with problems: |
4206 | * 1) We can delete sysfs objects which invoke hotplug | 4207 | * 1) We can delete sysfs objects which invoke hotplug |
4207 | * without deadlocking with linkwatch via keventd. | 4208 | * without deadlocking with linkwatch via keventd. |
4208 | * 2) Since we run with the RTNL semaphore not held, we can sleep | 4209 | * 2) Since we run with the RTNL semaphore not held, we can sleep |
4209 | * safely in order to wait for the netdev refcnt to drop to zero. | 4210 | * safely in order to wait for the netdev refcnt to drop to zero. |
4211 | * | ||
4212 | * We must not return until all unregister events added during | ||
4213 | * the interval the lock was held have been completed. | ||
4210 | */ | 4214 | */ |
4211 | static DEFINE_MUTEX(net_todo_run_mutex); | ||
4212 | void netdev_run_todo(void) | 4215 | void netdev_run_todo(void) |
4213 | { | 4216 | { |
4214 | struct list_head list; | 4217 | struct list_head list; |
4215 | 4218 | ||
4216 | /* Need to guard against multiple cpu's getting out of order. */ | ||
4217 | mutex_lock(&net_todo_run_mutex); | ||
4218 | |||
4219 | /* Not safe to do outside the semaphore. We must not return | ||
4220 | * until all unregister events invoked by the local processor | ||
4221 | * have been completed (either by this todo run, or one on | ||
4222 | * another cpu). | ||
4223 | */ | ||
4224 | if (list_empty(&net_todo_list)) | ||
4225 | goto out; | ||
4226 | |||
4227 | /* Snapshot list, allow later requests */ | 4219 | /* Snapshot list, allow later requests */ |
4228 | spin_lock(&net_todo_list_lock); | ||
4229 | list_replace_init(&net_todo_list, &list); | 4220 | list_replace_init(&net_todo_list, &list); |
4230 | spin_unlock(&net_todo_list_lock); | 4221 | |
4222 | __rtnl_unlock(); | ||
4231 | 4223 | ||
4232 | while (!list_empty(&list)) { | 4224 | while (!list_empty(&list)) { |
4233 | struct net_device *dev | 4225 | struct net_device *dev |
@@ -4259,9 +4251,6 @@ void netdev_run_todo(void) | |||
4259 | /* Free network device */ | 4251 | /* Free network device */ |
4260 | kobject_put(&dev->dev.kobj); | 4252 | kobject_put(&dev->dev.kobj); |
4261 | } | 4253 | } |
4262 | |||
4263 | out: | ||
4264 | mutex_unlock(&net_todo_run_mutex); | ||
4265 | } | 4254 | } |
4266 | 4255 | ||
4267 | static struct net_device_stats *internal_stats(struct net_device *dev) | 4256 | static struct net_device_stats *internal_stats(struct net_device *dev) |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 8862498fd4a6..3630131fa1fa 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -73,7 +73,7 @@ void __rtnl_unlock(void) | |||
73 | 73 | ||
74 | void rtnl_unlock(void) | 74 | void rtnl_unlock(void) |
75 | { | 75 | { |
76 | mutex_unlock(&rtnl_mutex); | 76 | /* This fellow will unlock it for us. */ |
77 | netdev_run_todo(); | 77 | netdev_run_todo(); |
78 | } | 78 | } |
79 | 79 | ||