From 4ef6acff83222f4496ceef7d1f0ee9e50a5bb403 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Thu, 1 Jul 2010 13:21:35 +0000 Subject: sched: qdisc_reset_all_tx is calling qdisc_reset without qdisc_lock When calling qdisc_reset() the qdisc lock needs to be held. In this case there is at least one driver i4l which is using this without holding the lock. Add the locking here. Signed-off-by: John Fastabend Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- include/net/sch_generic.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 03ca5d82675..ba749be1e35 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -317,8 +317,16 @@ extern void tcf_destroy_chain(struct tcf_proto **fl); static inline void qdisc_reset_all_tx(struct net_device *dev) { unsigned int i; - for (i = 0; i < dev->num_tx_queues; i++) - qdisc_reset(netdev_get_tx_queue(dev, i)->qdisc); + struct Qdisc *qdisc; + + for (i = 0; i < dev->num_tx_queues; i++) { + qdisc = netdev_get_tx_queue(dev, i)->qdisc; + if (qdisc) { + spin_lock_bh(qdisc_lock(qdisc)); + qdisc_reset(qdisc); + spin_unlock_bh(qdisc_lock(qdisc)); + } + } } /* Are all TX queues of the device empty? */ -- cgit v1.2.3