aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_generic.c')
-rw-r--r--net/sched/sch_generic.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 7c8e5d73d433..797ebef73642 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -56,6 +56,35 @@ static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
56 return 0; 56 return 0;
57} 57}
58 58
59static struct sk_buff *try_bulk_dequeue_skb(struct Qdisc *q,
60 struct sk_buff *head_skb,
61 int bytelimit)
62{
63 struct sk_buff *skb, *tail_skb = head_skb;
64
65 while (bytelimit > 0) {
66 skb = q->dequeue(q);
67 if (!skb)
68 break;
69
70 bytelimit -= skb->len; /* covers GSO len */
71 skb = validate_xmit_skb(skb, qdisc_dev(q));
72 if (!skb)
73 break;
74
75 while (tail_skb->next) /* GSO list goto tail */
76 tail_skb = tail_skb->next;
77
78 tail_skb->next = skb;
79 tail_skb = skb;
80 }
81
82 return head_skb;
83}
84
85/* Note that dequeue_skb can possibly return a SKB list (via skb->next).
86 * A requeued skb (via q->gso_skb) can also be a SKB list.
87 */
59static inline struct sk_buff *dequeue_skb(struct Qdisc *q) 88static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
60{ 89{
61 struct sk_buff *skb = q->gso_skb; 90 struct sk_buff *skb = q->gso_skb;
@@ -70,10 +99,17 @@ static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
70 } else 99 } else
71 skb = NULL; 100 skb = NULL;
72 } else { 101 } else {
73 if (!(q->flags & TCQ_F_ONETXQUEUE) || !netif_xmit_frozen_or_stopped(txq)) { 102 if (!(q->flags & TCQ_F_ONETXQUEUE) ||
103 !netif_xmit_frozen_or_stopped(txq)) {
104 int bytelimit = qdisc_avail_bulklimit(txq);
105
74 skb = q->dequeue(q); 106 skb = q->dequeue(q);
75 if (skb) 107 if (skb) {
108 bytelimit -= skb->len;
76 skb = validate_xmit_skb(skb, qdisc_dev(q)); 109 skb = validate_xmit_skb(skb, qdisc_dev(q));
110 }
111 if (skb && qdisc_may_bulk(q))
112 skb = try_bulk_dequeue_skb(q, skb, bytelimit);
77 } 113 }
78 } 114 }
79 115