diff options
author | John Fastabend <john.r.fastabend@intel.com> | 2010-07-01 13:21:35 (GMT) |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-07-03 04:59:07 (GMT) |
commit | 4ef6acff83222f4496ceef7d1f0ee9e50a5bb403 (patch) | |
tree | 0982d46258047f208c26068252457179f5f13bdf | |
parent | 7ae80abdba0644e12ac17da567a2db1efc1bf8a8 (diff) | |
download | linux-4ef6acff83222f4496ceef7d1f0ee9e50a5bb403.tar.xz |
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 <john.r.fastabend@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/sch_generic.h | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 03ca5d8..ba749be 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? */ |