From 5830725f8a36908111ecccf2899d06d6dcf54d45 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Thu, 10 May 2007 04:02:41 -0700 Subject: [NET]: Fix dev->qdisc race for NETDEV_TX_LOCKED case When transmit fails with NETDEV_TX_LOCKED the skb is requeued to dev->qdisc again. The dev->qdisc pointer is protected by the queue lock which needs to be dropped when attempting to transmit and acquired again before requeing. The problem is that qdisc_restart() fetches the dev->qdisc pointer once and stores it in the `q' variable which is invalidated when dropping the queue_lock, therefore the variable needs to be refreshed before requeueing. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/sched/sch_generic.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net/sched') diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 3385ee592541..a8240c578772 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -139,6 +139,7 @@ static inline int qdisc_restart(struct net_device *dev) } if (ret == NETDEV_TX_LOCKED && nolock) { spin_lock(&dev->queue_lock); + q = dev->qdisc; goto collision; } } -- cgit v1.2.3