aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sch_generic.h2
-rw-r--r--net/sched/sch_generic.c12
2 files changed, 8 insertions, 6 deletions
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index e5569625d2a5..3b983e8a0555 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -52,7 +52,7 @@ struct Qdisc
52 u32 parent; 52 u32 parent;
53 atomic_t refcnt; 53 atomic_t refcnt;
54 unsigned long state; 54 unsigned long state;
55 struct sk_buff *gso_skb; 55 struct sk_buff_head requeue;
56 struct sk_buff_head q; 56 struct sk_buff_head q;
57 struct netdev_queue *dev_queue; 57 struct netdev_queue *dev_queue;
58 struct Qdisc *next_sched; 58 struct Qdisc *next_sched;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index ec0a0839ce51..5961536be60c 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -45,7 +45,7 @@ static inline int qdisc_qlen(struct Qdisc *q)
45static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q) 45static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
46{ 46{
47 if (unlikely(skb->next)) 47 if (unlikely(skb->next))
48 q->gso_skb = skb; 48 __skb_queue_head(&q->requeue, skb);
49 else 49 else
50 q->ops->requeue(skb, q); 50 q->ops->requeue(skb, q);
51 51
@@ -57,9 +57,8 @@ static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
57{ 57{
58 struct sk_buff *skb; 58 struct sk_buff *skb;
59 59
60 if ((skb = q->gso_skb)) 60 skb = __skb_dequeue(&q->requeue);
61 q->gso_skb = NULL; 61 if (!skb)
62 else
63 skb = q->dequeue(q); 62 skb = q->dequeue(q);
64 63
65 return skb; 64 return skb;
@@ -327,6 +326,7 @@ struct Qdisc noop_qdisc = {
327 .flags = TCQ_F_BUILTIN, 326 .flags = TCQ_F_BUILTIN,
328 .ops = &noop_qdisc_ops, 327 .ops = &noop_qdisc_ops,
329 .list = LIST_HEAD_INIT(noop_qdisc.list), 328 .list = LIST_HEAD_INIT(noop_qdisc.list),
329 .requeue.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
330 .q.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock), 330 .q.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
331 .dev_queue = &noop_netdev_queue, 331 .dev_queue = &noop_netdev_queue,
332}; 332};
@@ -352,6 +352,7 @@ static struct Qdisc noqueue_qdisc = {
352 .flags = TCQ_F_BUILTIN, 352 .flags = TCQ_F_BUILTIN,
353 .ops = &noqueue_qdisc_ops, 353 .ops = &noqueue_qdisc_ops,
354 .list = LIST_HEAD_INIT(noqueue_qdisc.list), 354 .list = LIST_HEAD_INIT(noqueue_qdisc.list),
355 .requeue.lock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock),
355 .q.lock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock), 356 .q.lock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock),
356 .dev_queue = &noqueue_netdev_queue, 357 .dev_queue = &noqueue_netdev_queue,
357}; 358};
@@ -472,6 +473,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
472 sch->padded = (char *) sch - (char *) p; 473 sch->padded = (char *) sch - (char *) p;
473 474
474 INIT_LIST_HEAD(&sch->list); 475 INIT_LIST_HEAD(&sch->list);
476 skb_queue_head_init(&sch->requeue);
475 skb_queue_head_init(&sch->q); 477 skb_queue_head_init(&sch->q);
476 sch->ops = ops; 478 sch->ops = ops;
477 sch->enqueue = ops->enqueue; 479 sch->enqueue = ops->enqueue;
@@ -539,7 +541,7 @@ void qdisc_destroy(struct Qdisc *qdisc)
539 module_put(ops->owner); 541 module_put(ops->owner);
540 dev_put(qdisc_dev(qdisc)); 542 dev_put(qdisc_dev(qdisc));
541 543
542 kfree_skb(qdisc->gso_skb); 544 __skb_queue_purge(&qdisc->requeue);
543 545
544 kfree((char *) qdisc - qdisc->padded); 546 kfree((char *) qdisc - qdisc->padded);
545} 547}