aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-19 07:00:36 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-19 07:00:36 -0400
commit195648bbc5ae0848e82f771ecf4cd7497054c212 (patch)
tree644bc8685cab5f83225558888a4398cd0c93c919 /net/core
parentd2805395aadc105d7228511eb0f42d9eea912003 (diff)
pkt_sched: Prevent livelock in TX queue running.
If dev_deactivate() is trying to quiesce the queue, it is theoretically possible for another cpu to livelock trying to process that queue. This happens because dev_deactivate() grabs the queue spinlock as it checks the queue state, whereas net_tx_action() does a trylock and reschedules the qdisc if it hits the lock. This breaks the livelock by adding a check on __QDISC_STATE_DEACTIVATED to net_tx_action() when the trylock fails. Based upon feedback from Herbert Xu and Jarek Poplawski. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 8d133802372b..60c51f765887 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1990,7 +1990,9 @@ static void net_tx_action(struct softirq_action *h)
1990 qdisc_run(q); 1990 qdisc_run(q);
1991 spin_unlock(root_lock); 1991 spin_unlock(root_lock);
1992 } else { 1992 } else {
1993 __netif_reschedule(q); 1993 if (!test_bit(__QDISC_STATE_DEACTIVATED,
1994 &q->state))
1995 __netif_reschedule(q);
1994 } 1996 }
1995 } 1997 }
1996 } 1998 }