diff options
-rw-r--r-- | include/net/sch_generic.h | 1 | ||||
-rw-r--r-- | net/sched/sch_generic.c | 17 |
2 files changed, 14 insertions, 4 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 2092d33194dd..8da32678ce18 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h | |||
@@ -30,6 +30,7 @@ struct qdisc_rate_table { | |||
30 | enum qdisc_state_t { | 30 | enum qdisc_state_t { |
31 | __QDISC_STATE_SCHED, | 31 | __QDISC_STATE_SCHED, |
32 | __QDISC_STATE_DEACTIVATED, | 32 | __QDISC_STATE_DEACTIVATED, |
33 | __QDISC_STATE_RUNNING, | ||
33 | }; | 34 | }; |
34 | 35 | ||
35 | struct qdisc_size_table { | 36 | struct qdisc_size_table { |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 7e3fbe9cc936..39c144b6ff98 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -373,24 +373,33 @@ bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, | |||
373 | */ | 373 | */ |
374 | static inline bool qdisc_restart(struct Qdisc *q, int *packets) | 374 | static inline bool qdisc_restart(struct Qdisc *q, int *packets) |
375 | { | 375 | { |
376 | bool more, validate, nolock = q->flags & TCQ_F_NOLOCK; | ||
376 | spinlock_t *root_lock = NULL; | 377 | spinlock_t *root_lock = NULL; |
377 | struct netdev_queue *txq; | 378 | struct netdev_queue *txq; |
378 | struct net_device *dev; | 379 | struct net_device *dev; |
379 | struct sk_buff *skb; | 380 | struct sk_buff *skb; |
380 | bool validate; | ||
381 | 381 | ||
382 | /* Dequeue packet */ | 382 | /* Dequeue packet */ |
383 | if (nolock && test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) | ||
384 | return false; | ||
385 | |||
383 | skb = dequeue_skb(q, &validate, packets); | 386 | skb = dequeue_skb(q, &validate, packets); |
384 | if (unlikely(!skb)) | 387 | if (unlikely(!skb)) { |
388 | if (nolock) | ||
389 | clear_bit(__QDISC_STATE_RUNNING, &q->state); | ||
385 | return false; | 390 | return false; |
391 | } | ||
386 | 392 | ||
387 | if (!(q->flags & TCQ_F_NOLOCK)) | 393 | if (!nolock) |
388 | root_lock = qdisc_lock(q); | 394 | root_lock = qdisc_lock(q); |
389 | 395 | ||
390 | dev = qdisc_dev(q); | 396 | dev = qdisc_dev(q); |
391 | txq = skb_get_tx_queue(dev, skb); | 397 | txq = skb_get_tx_queue(dev, skb); |
392 | 398 | ||
393 | return sch_direct_xmit(skb, q, dev, txq, root_lock, validate); | 399 | more = sch_direct_xmit(skb, q, dev, txq, root_lock, validate); |
400 | if (nolock) | ||
401 | clear_bit(__QDISC_STATE_RUNNING, &q->state); | ||
402 | return more; | ||
394 | } | 403 | } |
395 | 404 | ||
396 | void __qdisc_run(struct Qdisc *q) | 405 | void __qdisc_run(struct Qdisc *q) |