aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_if.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-02-22 04:10:18 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2007-02-26 14:42:59 -0500
commit269def7c505b4d229f9ad49bf88543d1e605533e (patch)
tree341377271f16c0def001a876217a8e6f430d75b4 /net/bridge/br_if.c
parentac062e84d0c177c43549e7fb608152fec218e7fc (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.c30
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 */
80static void port_carrier_check(struct work_struct *work) 80void 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 }
110done:
111 dev_put(dev);
112 rtnl_unlock();
113} 99}
114 100
115static void release_nbp(struct kobject *kobj) 101static 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;