aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2008-08-05 21:42:51 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-05 21:42:51 -0400
commitef647f1300d69adb8223d970554d59d7e244db6d (patch)
tree627503820872ec530049ad0bcfd16d09c9008b3f
parent33e334950abda8e42c3b6e6f280fad0d4ab92141 (diff)
bridge: Eliminate unnecessary forward delay
From: Stephen Hemminger <shemminger@vyatta.com> Based upon original patch by Herbert Xu, which contained the following problem description: -------------------- When the forward delay is set to zero, we still delay the setting of the forwarding state by one or possibly two timers depending on whether STP is enabled. This could either turn out to be instantaneous, or horribly slow depending on the load of the machine. As there is nothing preventing us from enabling forwarding straight away, this patch eliminates this potential delay by executing the code directly if the forward delay is zero. The effect of this problem is that immediately after the carrier comes on a port, the bridge will drop all packets received from that port until it enters forwarding mode, thus causing unnecessary packet loss. Note that this patch doesn't fully remove the delay due to the link watcher. We should also check the carrier state when we are about to drop an incoming packet because the port is disabled. But that's for another patch. -------------------- This version of the fix takes a different approach, in that it just does the state change directly. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/bridge/br_stp.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index 921bbe5cb94a..6e63ec3f1fcf 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -368,14 +368,25 @@ static void br_make_blocking(struct net_bridge_port *p)
368/* called under bridge lock */ 368/* called under bridge lock */
369static void br_make_forwarding(struct net_bridge_port *p) 369static void br_make_forwarding(struct net_bridge_port *p)
370{ 370{
371 if (p->state == BR_STATE_BLOCKING) { 371 struct net_bridge *br = p->br;
372 if (p->br->stp_enabled == BR_KERNEL_STP)
373 p->state = BR_STATE_LISTENING;
374 else
375 p->state = BR_STATE_LEARNING;
376 372
377 br_log_state(p); 373 if (p->state != BR_STATE_BLOCKING)
378 mod_timer(&p->forward_delay_timer, jiffies + p->br->forward_delay); } 374 return;
375
376 if (br->forward_delay == 0) {
377 p->state = BR_STATE_FORWARDING;
378 br_topology_change_detection(br);
379 del_timer(&p->forward_delay_timer);
380 }
381 else if (p->br->stp_enabled == BR_KERNEL_STP)
382 p->state = BR_STATE_LISTENING;
383 else
384 p->state = BR_STATE_LEARNING;
385
386 br_log_state(p);
387
388 if (br->forward_delay != 0)
389 mod_timer(&p->forward_delay_timer, jiffies + br->forward_delay);
379} 390}
380 391
381/* called under bridge lock */ 392/* called under bridge lock */