mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-14 04:41:26 +00:00
[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>
This commit is contained in:
parent
0f4821e7b9
commit
cacaddf57e
@ -16,6 +16,7 @@
|
|||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
#include <linux/if.h>
|
#include <linux/if.h>
|
||||||
#include <net/sock.h>
|
#include <net/sock.h>
|
||||||
|
#include <net/pkt_sched.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
@ -74,6 +75,12 @@ void linkwatch_run_queue(void)
|
|||||||
clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state);
|
clear_bit(__LINK_STATE_LINKWATCH_PENDING, &dev->state);
|
||||||
|
|
||||||
if (dev->flags & IFF_UP) {
|
if (dev->flags & IFF_UP) {
|
||||||
|
if (netif_carrier_ok(dev)) {
|
||||||
|
WARN_ON(dev->qdisc_sleeping == &noop_qdisc);
|
||||||
|
dev_activate(dev);
|
||||||
|
} else
|
||||||
|
dev_deactivate(dev);
|
||||||
|
|
||||||
netdev_state_change(dev);
|
netdev_state_change(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,6 +539,10 @@ void dev_activate(struct net_device *dev)
|
|||||||
write_unlock_bh(&qdisc_tree_lock);
|
write_unlock_bh(&qdisc_tree_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!netif_carrier_ok(dev))
|
||||||
|
/* Delay activation until next carrier-on event */
|
||||||
|
return;
|
||||||
|
|
||||||
spin_lock_bh(&dev->queue_lock);
|
spin_lock_bh(&dev->queue_lock);
|
||||||
rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping);
|
rcu_assign_pointer(dev->qdisc, dev->qdisc_sleeping);
|
||||||
if (dev->qdisc != &noqueue_qdisc) {
|
if (dev->qdisc != &noqueue_qdisc) {
|
||||||
|
Loading…
Reference in New Issue
Block a user