diff options
Diffstat (limited to 'net/sched/sch_qfq.c')
| -rw-r--r-- | net/sched/sch_qfq.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index dc37c4ead439..29f5c4a24688 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c | |||
| @@ -1210,10 +1210,12 @@ static struct qfq_aggregate *qfq_choose_next_agg(struct qfq_sched *q) | |||
| 1210 | static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, | 1210 | static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, |
| 1211 | struct sk_buff **to_free) | 1211 | struct sk_buff **to_free) |
| 1212 | { | 1212 | { |
| 1213 | unsigned int len = qdisc_pkt_len(skb), gso_segs; | ||
| 1213 | struct qfq_sched *q = qdisc_priv(sch); | 1214 | struct qfq_sched *q = qdisc_priv(sch); |
| 1214 | struct qfq_class *cl; | 1215 | struct qfq_class *cl; |
| 1215 | struct qfq_aggregate *agg; | 1216 | struct qfq_aggregate *agg; |
| 1216 | int err = 0; | 1217 | int err = 0; |
| 1218 | bool first; | ||
| 1217 | 1219 | ||
| 1218 | cl = qfq_classify(skb, sch, &err); | 1220 | cl = qfq_classify(skb, sch, &err); |
| 1219 | if (cl == NULL) { | 1221 | if (cl == NULL) { |
| @@ -1224,17 +1226,18 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, | |||
| 1224 | } | 1226 | } |
| 1225 | pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); | 1227 | pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid); |
| 1226 | 1228 | ||
| 1227 | if (unlikely(cl->agg->lmax < qdisc_pkt_len(skb))) { | 1229 | if (unlikely(cl->agg->lmax < len)) { |
| 1228 | pr_debug("qfq: increasing maxpkt from %u to %u for class %u", | 1230 | pr_debug("qfq: increasing maxpkt from %u to %u for class %u", |
| 1229 | cl->agg->lmax, qdisc_pkt_len(skb), cl->common.classid); | 1231 | cl->agg->lmax, len, cl->common.classid); |
| 1230 | err = qfq_change_agg(sch, cl, cl->agg->class_weight, | 1232 | err = qfq_change_agg(sch, cl, cl->agg->class_weight, len); |
| 1231 | qdisc_pkt_len(skb)); | ||
| 1232 | if (err) { | 1233 | if (err) { |
| 1233 | cl->qstats.drops++; | 1234 | cl->qstats.drops++; |
| 1234 | return qdisc_drop(skb, sch, to_free); | 1235 | return qdisc_drop(skb, sch, to_free); |
| 1235 | } | 1236 | } |
| 1236 | } | 1237 | } |
| 1237 | 1238 | ||
| 1239 | gso_segs = skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1; | ||
| 1240 | first = !cl->qdisc->q.qlen; | ||
| 1238 | err = qdisc_enqueue(skb, cl->qdisc, to_free); | 1241 | err = qdisc_enqueue(skb, cl->qdisc, to_free); |
| 1239 | if (unlikely(err != NET_XMIT_SUCCESS)) { | 1242 | if (unlikely(err != NET_XMIT_SUCCESS)) { |
| 1240 | pr_debug("qfq_enqueue: enqueue failed %d\n", err); | 1243 | pr_debug("qfq_enqueue: enqueue failed %d\n", err); |
| @@ -1245,16 +1248,17 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, | |||
| 1245 | return err; | 1248 | return err; |
| 1246 | } | 1249 | } |
| 1247 | 1250 | ||
| 1248 | bstats_update(&cl->bstats, skb); | 1251 | cl->bstats.bytes += len; |
| 1249 | qdisc_qstats_backlog_inc(sch, skb); | 1252 | cl->bstats.packets += gso_segs; |
| 1253 | sch->qstats.backlog += len; | ||
| 1250 | ++sch->q.qlen; | 1254 | ++sch->q.qlen; |
| 1251 | 1255 | ||
| 1252 | agg = cl->agg; | 1256 | agg = cl->agg; |
| 1253 | /* if the queue was not empty, then done here */ | 1257 | /* if the queue was not empty, then done here */ |
| 1254 | if (cl->qdisc->q.qlen != 1) { | 1258 | if (!first) { |
| 1255 | if (unlikely(skb == cl->qdisc->ops->peek(cl->qdisc)) && | 1259 | if (unlikely(skb == cl->qdisc->ops->peek(cl->qdisc)) && |
| 1256 | list_first_entry(&agg->active, struct qfq_class, alist) | 1260 | list_first_entry(&agg->active, struct qfq_class, alist) |
| 1257 | == cl && cl->deficit < qdisc_pkt_len(skb)) | 1261 | == cl && cl->deficit < len) |
| 1258 | list_move_tail(&cl->alist, &agg->active); | 1262 | list_move_tail(&cl->alist, &agg->active); |
| 1259 | 1263 | ||
| 1260 | return err; | 1264 | return err; |
