aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_qfq.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_qfq.c')
-rw-r--r--net/sched/sch_qfq.c20
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)
1210static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, 1210static 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;