aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorTommy S. Christensen <tommy.christensen@tpack.net>2005-05-03 19:18:52 -0400
committerDavid S. Miller <davem@davemloft.net>2005-05-03 19:18:52 -0400
commitcacaddf57ed4d5ca994e9a7e2bd5558061f5d89d (patch)
tree6e4c59a9a27441a3196cbc67a3a79356baa679fb /net
parent0f4821e7b93fe72e89b8ff393bd8e705bd178aa5 (diff)
[NET]: Disable queueing when carrier is lost.
Some network drivers call netif_stop_queue() when detecting loss of carrier. This leads to packets being queued up at the qdisc level for an unbound period of time. In order to prevent this effect, the core networking stack will now cease to queue packets for any device, that is operationally down (i.e. the queue is flushed and disabled). Signed-off-by: Tommy S. Christensen <tommy.christensen@tpack.net> Acked-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/link_watch.c7
-rw-r--r--net/sched/sch_generic.c4
2 files changed, 11 insertions, 0 deletions
diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index 4859b7446c6f..d43d1201275c 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -16,6 +16,7 @@
16#include <linux/netdevice.h> 16#include <linux/netdevice.h>
17#include <linux/if.h> 17#include <linux/if.h>
18#include <net/sock.h> 18#include <net/sock.h>
19#include <net/pkt_sched.h>
19#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
20#include <linux/jiffies.h> 21#include <linux/jiffies.h>
21#include <linux/spinlock.h> 22#include <linux/spinlock.h>
@@ -74,6 +75,12 @@ void linkwatch_run_queue(void)
74 clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state); 75 clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state);
75 76
76 if (dev->flags & IFF_UP) { 77 if (dev->flags & IFF_UP) {
78 if (netif_carrier_ok(dev)) {
79 WARN_ON(dev->qdisc_sleeping == &noop_qdisc);
80 dev_activate(dev);
81 } else
82 dev_deactivate(dev);
83
77 netdev_state_change(dev); 84 netdev_state_change(dev);
78 } 85 }
79 86
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 8c01e023f02e..9a2f8e41a26e 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -539,6 +539,10 @@ void dev_activate(struct net_device *dev)
539 write_unlock_bh(&qdisc_tree_lock); 539 write_unlock_bh(&qdisc_tree_lock);
540 } 540 }
541 541
542 if (!netif_carrier_ok(dev))
543 /* Delay activation until next carrier-on event */
544 return;
545
542 spin_lock_bh(&dev->queue_lock); 546 spin_lock_bh(&dev->queue_lock);
543 rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping); 547 rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping);
544 if (dev->qdisc != &noqueue_qdisc) { 548 if (dev->qdisc != &noqueue_qdisc) {