aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-02 23:02:43 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-02 23:02:43 -0400
commit5fb662297b8a4bdadd60371c34b760efca948ebc (patch)
treeef1def70cfa440ab3d367f6f67d466227ffdf0ef /net/core
parent82f97b8d3cb3982ec97e081598c671fab2c321b0 (diff)
pkt_sched: Use qdisc_lock() on already sampled root qdisc.
Based upon a bug report by Jeff Kirsher. Don't use qdisc_root_lock() in these cases as the root qdisc could have been changed, and we'd thus lock the wrong object. Tested by Emil S Tantilov who confirms that this seems to fix the problem. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index 69320a56a08..da7acacf02b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1796,7 +1796,7 @@ gso:
1796 skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS); 1796 skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS);
1797#endif 1797#endif
1798 if (q->enqueue) { 1798 if (q->enqueue) {
1799 spinlock_t *root_lock = qdisc_root_lock(q); 1799 spinlock_t *root_lock = qdisc_lock(q);
1800 1800
1801 spin_lock(root_lock); 1801 spin_lock(root_lock);
1802 1802
@@ -1995,7 +1995,7 @@ static void net_tx_action(struct softirq_action *h)
1995 smp_mb__before_clear_bit(); 1995 smp_mb__before_clear_bit();
1996 clear_bit(__QDISC_STATE_SCHED, &q->state); 1996 clear_bit(__QDISC_STATE_SCHED, &q->state);
1997 1997
1998 root_lock = qdisc_root_lock(q); 1998 root_lock = qdisc_lock(q);
1999 if (spin_trylock(root_lock)) { 1999 if (spin_trylock(root_lock)) {
2000 qdisc_run(q); 2000 qdisc_run(q);
2001 spin_unlock(root_lock); 2001 spin_unlock(root_lock);