diff options
author | Stephen Hemminger <shemminger@linux-foundation.org> | 2007-02-22 04:10:18 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-02-26 14:42:59 -0500 |
commit | 269def7c505b4d229f9ad49bf88543d1e605533e (patch) | |
tree | 341377271f16c0def001a876217a8e6f430d75b4 /net/bridge/br_if.c | |
parent | ac062e84d0c177c43549e7fb608152fec218e7fc (diff) |
[BRIDGE]: eliminate workqueue for carrier check
Having a work queue for checking carrier leads to lots of race issues.
Simpler to just get the cost when data structure is created and
update on change.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_if.c')
-rw-r--r-- | net/bridge/br_if.c | 30 |
1 files changed, 5 insertions, 25 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index aff6a779c9c8..6845a258408f 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -77,26 +77,15 @@ static int port_cost(struct net_device *dev) | |||
77 | * Called from work queue to allow for calling functions that | 77 | * Called from work queue to allow for calling functions that |
78 | * might sleep (such as speed check), and to debounce. | 78 | * might sleep (such as speed check), and to debounce. |
79 | */ | 79 | */ |
80 | static void port_carrier_check(struct work_struct *work) | 80 | void br_port_carrier_check(struct net_bridge_port *p) |
81 | { | 81 | { |
82 | struct net_bridge_port *p; | 82 | struct net_device *dev = p->dev; |
83 | struct net_device *dev; | 83 | struct net_bridge *br = p->br; |
84 | struct net_bridge *br; | ||
85 | |||
86 | dev = container_of(work, struct net_bridge_port, | ||
87 | carrier_check.work)->dev; | ||
88 | work_release(work); | ||
89 | |||
90 | rtnl_lock(); | ||
91 | p = dev->br_port; | ||
92 | if (!p) | ||
93 | goto done; | ||
94 | br = p->br; | ||
95 | 84 | ||
96 | if (netif_carrier_ok(dev)) | 85 | if (netif_carrier_ok(dev)) |
97 | p->path_cost = port_cost(dev); | 86 | p->path_cost = port_cost(dev); |
98 | 87 | ||
99 | if (br->dev->flags & IFF_UP) { | 88 | if (netif_running(br->dev)) { |
100 | spin_lock_bh(&br->lock); | 89 | spin_lock_bh(&br->lock); |
101 | if (netif_carrier_ok(dev)) { | 90 | if (netif_carrier_ok(dev)) { |
102 | if (p->state == BR_STATE_DISABLED) | 91 | if (p->state == BR_STATE_DISABLED) |
@@ -107,9 +96,6 @@ static void port_carrier_check(struct work_struct *work) | |||
107 | } | 96 | } |
108 | spin_unlock_bh(&br->lock); | 97 | spin_unlock_bh(&br->lock); |
109 | } | 98 | } |
110 | done: | ||
111 | dev_put(dev); | ||
112 | rtnl_unlock(); | ||
113 | } | 99 | } |
114 | 100 | ||
115 | static void release_nbp(struct kobject *kobj) | 101 | static void release_nbp(struct kobject *kobj) |
@@ -162,9 +148,6 @@ static void del_nbp(struct net_bridge_port *p) | |||
162 | 148 | ||
163 | dev_set_promiscuity(dev, -1); | 149 | dev_set_promiscuity(dev, -1); |
164 | 150 | ||
165 | if (cancel_delayed_work(&p->carrier_check)) | ||
166 | dev_put(dev); | ||
167 | |||
168 | spin_lock_bh(&br->lock); | 151 | spin_lock_bh(&br->lock); |
169 | br_stp_disable_port(p); | 152 | br_stp_disable_port(p); |
170 | spin_unlock_bh(&br->lock); | 153 | spin_unlock_bh(&br->lock); |
@@ -282,7 +265,6 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, | |||
282 | p->port_no = index; | 265 | p->port_no = index; |
283 | br_init_port(p); | 266 | br_init_port(p); |
284 | p->state = BR_STATE_DISABLED; | 267 | p->state = BR_STATE_DISABLED; |
285 | INIT_DELAYED_WORK_NAR(&p->carrier_check, port_carrier_check); | ||
286 | br_stp_port_timer_init(p); | 268 | br_stp_port_timer_init(p); |
287 | 269 | ||
288 | kobject_init(&p->kobj); | 270 | kobject_init(&p->kobj); |
@@ -446,12 +428,10 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
446 | spin_lock_bh(&br->lock); | 428 | spin_lock_bh(&br->lock); |
447 | br_stp_recalculate_bridge_id(br); | 429 | br_stp_recalculate_bridge_id(br); |
448 | br_features_recompute(br); | 430 | br_features_recompute(br); |
449 | if (schedule_delayed_work(&p->carrier_check, BR_PORT_DEBOUNCE)) | ||
450 | dev_hold(dev); | ||
451 | |||
452 | spin_unlock_bh(&br->lock); | 431 | spin_unlock_bh(&br->lock); |
453 | 432 | ||
454 | dev_set_mtu(br->dev, br_min_mtu(br)); | 433 | dev_set_mtu(br->dev, br_min_mtu(br)); |
434 | |||
455 | kobject_uevent(&p->kobj, KOBJ_ADD); | 435 | kobject_uevent(&p->kobj, KOBJ_ADD); |
456 | 436 | ||
457 | return 0; | 437 | return 0; |