diff options
| author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-10-28 01:35:35 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2009-10-29 04:13:48 -0400 |
| commit | 8c56ba0530af3d5eee6445dce9dc9296f1f74ed5 (patch) | |
| tree | b7c82f62e266ba732e0a80f9c22a91d47cddafe3 /net/bridge | |
| parent | 59fd5d87a4243a992f3a3e69f3627cf4c509608e (diff) | |
bridge: Optimize multiple unregistration
Speedup module unloading by factorizing synchronize_rcu() calls
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
| -rw-r--r-- | net/bridge/br_if.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index b1b3b0fbf41..2117e5ba24c 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -154,7 +154,7 @@ static void del_nbp(struct net_bridge_port *p) | |||
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | /* called with RTNL */ | 156 | /* called with RTNL */ |
| 157 | static void del_br(struct net_bridge *br) | 157 | static void del_br(struct net_bridge *br, struct list_head *head) |
| 158 | { | 158 | { |
| 159 | struct net_bridge_port *p, *n; | 159 | struct net_bridge_port *p, *n; |
| 160 | 160 | ||
| @@ -165,7 +165,7 @@ static void del_br(struct net_bridge *br) | |||
| 165 | del_timer_sync(&br->gc_timer); | 165 | del_timer_sync(&br->gc_timer); |
| 166 | 166 | ||
| 167 | br_sysfs_delbr(br->dev); | 167 | br_sysfs_delbr(br->dev); |
| 168 | unregister_netdevice(br->dev); | 168 | unregister_netdevice_queue(br->dev, head); |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static struct net_device *new_bridge_dev(struct net *net, const char *name) | 171 | static struct net_device *new_bridge_dev(struct net *net, const char *name) |
| @@ -323,7 +323,7 @@ int br_del_bridge(struct net *net, const char *name) | |||
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | else | 325 | else |
| 326 | del_br(netdev_priv(dev)); | 326 | del_br(netdev_priv(dev), NULL); |
| 327 | 327 | ||
| 328 | rtnl_unlock(); | 328 | rtnl_unlock(); |
| 329 | return ret; | 329 | return ret; |
| @@ -462,15 +462,14 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
| 462 | void br_net_exit(struct net *net) | 462 | void br_net_exit(struct net *net) |
| 463 | { | 463 | { |
| 464 | struct net_device *dev; | 464 | struct net_device *dev; |
| 465 | LIST_HEAD(list); | ||
| 465 | 466 | ||
| 466 | rtnl_lock(); | 467 | rtnl_lock(); |
| 467 | restart: | 468 | for_each_netdev(net, dev) |
| 468 | for_each_netdev(net, dev) { | 469 | if (dev->priv_flags & IFF_EBRIDGE) |
| 469 | if (dev->priv_flags & IFF_EBRIDGE) { | 470 | del_br(netdev_priv(dev), &list); |
| 470 | del_br(netdev_priv(dev)); | 471 | |
| 471 | goto restart; | 472 | unregister_netdevice_many(&list); |
| 472 | } | ||
| 473 | } | ||
| 474 | rtnl_unlock(); | 473 | rtnl_unlock(); |
| 475 | 474 | ||
| 476 | } | 475 | } |
