aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/netdevice.h
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2009-11-17 00:59:21 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-18 08:03:11 -0500
commite014debecd3ee3832e6476b3a9c948edfcfd1250 (patch)
tree9b73836a5dc3c1df92b17037a12bbbfaf5f495d3 /include/linux/netdevice.h
parente2ce146848c81af2f6d42e67990191c284bf0c33 (diff)
linkwatch: linkwatch_forget_dev() to speedup device dismantle
Herbert Xu a écrit : > On Tue, Nov 17, 2009 at 04:26:04AM -0800, David Miller wrote: >> Really, the link watch stuff is just due for a redesign. I don't >> think a simple hack is going to cut it this time, sorry Eric :-) > > I have no objections against any redesigns, but since the only > caller of linkwatch_forget_dev runs in process context with the > RTNL, it could also legally emit those events. Thanks guys, here an updated version then, before linkwatch surgery ? In this version, I force the event to be sent synchronously. [PATCH net-next-2.6] linkwatch: linkwatch_forget_dev() to speedup device dismantle time ip link del eth3.103 ; time ip link del eth3.104 ; time ip link del eth3.105 real 0m0.266s user 0m0.000s sys 0m0.001s real 0m0.770s user 0m0.000s sys 0m0.000s real 0m1.022s user 0m0.000s sys 0m0.000s One problem of current schem in vlan dismantle phase is the holding of device done by following chain : vlan_dev_stop() -> netif_carrier_off(dev) -> linkwatch_fire_event(dev) -> dev_hold() ... And __linkwatch_run_queue() runs up to one second later... A generic fix to this problem is to add a linkwatch_forget_dev() method to unlink the device from the list of watched devices. dev->link_watch_next becomes dev->link_watch_list (and use a bit more memory), to be able to unlink device in O(1). After patch : time ip link del eth3.103 ; time ip link del eth3.104 ; time ip link del eth3.105 real 0m0.024s user 0m0.000s sys 0m0.000s real 0m0.032s user 0m0.000s sys 0m0.001s real 0m0.033s user 0m0.000s sys 0m0.000s Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/netdevice.h')
-rw-r--r--include/linux/netdevice.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index c8fa4627de00..97873e31661c 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -896,7 +896,7 @@ struct net_device {
896 /* device index hash chain */ 896 /* device index hash chain */
897 struct hlist_node index_hlist; 897 struct hlist_node index_hlist;
898 898
899 struct net_device *link_watch_next; 899 struct list_head link_watch_list;
900 900
901 /* register/unregister state machine */ 901 /* register/unregister state machine */
902 enum { NETREG_UNINITIALIZED=0, 902 enum { NETREG_UNINITIALIZED=0,
@@ -1600,6 +1600,7 @@ static inline void dev_hold(struct net_device *dev)
1600 */ 1600 */
1601 1601
1602extern void linkwatch_fire_event(struct net_device *dev); 1602extern void linkwatch_fire_event(struct net_device *dev);
1603extern void linkwatch_forget_dev(struct net_device *dev);
1603 1604
1604/** 1605/**
1605 * netif_carrier_ok - test if carrier present 1606 * netif_carrier_ok - test if carrier present