1
2
3
4
5
6
7
8
9
10
11#include <linux/module.h>
12#include <linux/init.h>
13#include <linux/bitops.h>
14#include <linux/errno.h>
15#include <linux/netdevice.h>
16#include <linux/pkt_sched.h>
17#include <net/sch_generic.h>
18#include <net/pkt_sched.h>
19#include <net/pkt_cls.h>
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76#define QFQ_MAX_SLOTS 32
77
78
79
80
81
82
83
84
85
86
87#define QFQ_MAX_INDEX 24
88#define QFQ_MAX_WSHIFT 12
89
90#define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT)
91#define QFQ_MAX_WSUM (16*QFQ_MAX_WEIGHT)
92
93#define FRAC_BITS 30
94#define ONE_FP (1UL << FRAC_BITS)
95#define IWSUM (ONE_FP/QFQ_MAX_WSUM)
96
97#define QFQ_MTU_SHIFT 16
98#define QFQ_MIN_SLOT_SHIFT (FRAC_BITS + QFQ_MTU_SHIFT - QFQ_MAX_INDEX)
99#define QFQ_MIN_LMAX 256
100
101
102
103
104
105enum qfq_state { ER, IR, EB, IB, QFQ_MAX_STATE };
106
107struct qfq_group;
108
109struct qfq_class {
110 struct Qdisc_class_common common;
111
112 unsigned int refcnt;
113 unsigned int filter_cnt;
114
115 struct gnet_stats_basic_packed bstats;
116 struct gnet_stats_queue qstats;
117 struct gnet_stats_rate_est rate_est;
118 struct Qdisc *qdisc;
119
120 struct hlist_node next;
121 u64 S, F;
122
123
124
125
126
127 struct qfq_group *grp;
128
129
130 u32 inv_w;
131 u32 lmax;
132};
133
134struct qfq_group {
135 u64 S, F;
136 unsigned int slot_shift;
137 unsigned int index;
138 unsigned int front;
139 unsigned long full_slots;
140
141
142 struct hlist_head slots[QFQ_MAX_SLOTS];
143};
144
145struct qfq_sched {
146 struct tcf_proto *filter_list;
147 struct Qdisc_class_hash clhash;
148
149 u64 V;
150 u32 wsum;
151
152 unsigned long bitmaps[QFQ_MAX_STATE];
153 struct qfq_group groups[QFQ_MAX_INDEX + 1];
154};
155
156static struct qfq_class *qfq_find_class(struct Qdisc *sch, u32 classid)
157{
158 struct qfq_sched *q = qdisc_priv(sch);
159 struct Qdisc_class_common *clc;
160
161 clc = qdisc_class_find(&q->clhash, classid);
162 if (clc == NULL)
163 return NULL;
164 return container_of(clc, struct qfq_class, common);
165}
166
167static void qfq_purge_queue(struct qfq_class *cl)
168{
169 unsigned int len = cl->qdisc->q.qlen;
170
171 qdisc_reset(cl->qdisc);
172 qdisc_tree_decrease_qlen(cl->qdisc, len);
173}
174
175static const struct nla_policy qfq_policy[TCA_QFQ_MAX + 1] = {
176 [TCA_QFQ_WEIGHT] = { .type = NLA_U32 },
177 [TCA_QFQ_LMAX] = { .type = NLA_U32 },
178};
179
180
181
182
183
184
185static int qfq_calc_index(u32 inv_w, unsigned int maxlen)
186{
187 u64 slot_size = (u64)maxlen * inv_w;
188 unsigned long size_map;
189 int index = 0;
190
191 size_map = slot_size >> QFQ_MIN_SLOT_SHIFT;
192 if (!size_map)
193 goto out;
194
195 index = __fls(size_map) + 1;
196 index -= !(slot_size - (1ULL << (index + QFQ_MIN_SLOT_SHIFT - 1)));
197
198 if (index < 0)
199 index = 0;
200out:
201 pr_debug("qfq calc_index: W = %lu, L = %u, I = %d\n",
202 (unsigned long) ONE_FP/inv_w, maxlen, index);
203
204 return index;
205}
206
207
208static unsigned int qdisc_peek_len(struct Qdisc *sch)
209{
210 struct sk_buff *skb;
211
212 skb = sch->ops->peek(sch);
213 return skb ? qdisc_pkt_len(skb) : 0;
214}
215
216static void qfq_deactivate_class(struct qfq_sched *, struct qfq_class *);
217static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl,
218 unsigned int len);
219
220static void qfq_update_class_params(struct qfq_sched *q, struct qfq_class *cl,
221 u32 lmax, u32 inv_w, int delta_w)
222{
223 int i;
224
225
226 cl->lmax = lmax;
227 cl->inv_w = inv_w;
228 i = qfq_calc_index(cl->inv_w, cl->lmax);
229
230 cl->grp = &q->groups[i];
231
232 q->wsum += delta_w;
233}
234
235static void qfq_update_reactivate_class(struct qfq_sched *q,
236 struct qfq_class *cl,
237 u32 inv_w, u32 lmax, int delta_w)
238{
239 bool need_reactivation = false;
240 int i = qfq_calc_index(inv_w, lmax);
241
242 if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) {
243
244
245
246
247
248 cl->F = cl->S;
249
250 qfq_deactivate_class(q, cl);
251 need_reactivation = true;
252 }
253
254 qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
255
256 if (need_reactivation)
257 qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc));
258}
259
260
261static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
262 struct nlattr **tca, unsigned long *arg)
263{
264 struct qfq_sched *q = qdisc_priv(sch);
265 struct qfq_class *cl = (struct qfq_class *)*arg;
266 struct nlattr *tb[TCA_QFQ_MAX + 1];
267 u32 weight, lmax, inv_w;
268 int err;
269 int delta_w;
270
271 if (tca[TCA_OPTIONS] == NULL) {
272 pr_notice("qfq: no options\n");
273 return -EINVAL;
274 }
275
276 err = nla_parse_nested(tb, TCA_QFQ_MAX, tca[TCA_OPTIONS], qfq_policy);
277 if (err < 0)
278 return err;
279
280 if (tb[TCA_QFQ_WEIGHT]) {
281 weight = nla_get_u32(tb[TCA_QFQ_WEIGHT]);
282 if (!weight || weight > (1UL << QFQ_MAX_WSHIFT)) {
283 pr_notice("qfq: invalid weight %u\n", weight);
284 return -EINVAL;
285 }
286 } else
287 weight = 1;
288
289 inv_w = ONE_FP / weight;
290 weight = ONE_FP / inv_w;
291 delta_w = weight - (cl ? ONE_FP / cl->inv_w : 0);
292 if (q->wsum + delta_w > QFQ_MAX_WSUM) {
293 pr_notice("qfq: total weight out of range (%u + %u)\n",
294 delta_w, q->wsum);
295 return -EINVAL;
296 }
297
298 if (tb[TCA_QFQ_LMAX]) {
299 lmax = nla_get_u32(tb[TCA_QFQ_LMAX]);
300 if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) {
301 pr_notice("qfq: invalid max length %u\n", lmax);
302 return -EINVAL;
303 }
304 } else
305 lmax = psched_mtu(qdisc_dev(sch));
306
307 if (cl != NULL) {
308 if (tca[TCA_RATE]) {
309 err = gen_replace_estimator(&cl->bstats, &cl->rate_est,
310 qdisc_root_sleeping_lock(sch),
311 tca[TCA_RATE]);
312 if (err)
313 return err;
314 }
315
316 if (lmax == cl->lmax && inv_w == cl->inv_w)
317 return 0;
318
319 sch_tree_lock(sch);
320 qfq_update_reactivate_class(q, cl, inv_w, lmax, delta_w);
321 sch_tree_unlock(sch);
322
323 return 0;
324 }
325
326 cl = kzalloc(sizeof(struct qfq_class), GFP_KERNEL);
327 if (cl == NULL)
328 return -ENOBUFS;
329
330 cl->refcnt = 1;
331 cl->common.classid = classid;
332
333 qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
334
335 cl->qdisc = qdisc_create_dflt(sch->dev_queue,
336 &pfifo_qdisc_ops, classid);
337 if (cl->qdisc == NULL)
338 cl->qdisc = &noop_qdisc;
339
340 if (tca[TCA_RATE]) {
341 err = gen_new_estimator(&cl->bstats, &cl->rate_est,
342 qdisc_root_sleeping_lock(sch),
343 tca[TCA_RATE]);
344 if (err) {
345 qdisc_destroy(cl->qdisc);
346 kfree(cl);
347 return err;
348 }
349 }
350
351 sch_tree_lock(sch);
352 qdisc_class_hash_insert(&q->clhash, &cl->common);
353 sch_tree_unlock(sch);
354
355 qdisc_class_hash_grow(sch, &q->clhash);
356
357 *arg = (unsigned long)cl;
358 return 0;
359}
360
361static void qfq_destroy_class(struct Qdisc *sch, struct qfq_class *cl)
362{
363 struct qfq_sched *q = qdisc_priv(sch);
364
365 if (cl->inv_w) {
366 q->wsum -= ONE_FP / cl->inv_w;
367 cl->inv_w = 0;
368 }
369
370 gen_kill_estimator(&cl->bstats, &cl->rate_est);
371 qdisc_destroy(cl->qdisc);
372 kfree(cl);
373}
374
375static int qfq_delete_class(struct Qdisc *sch, unsigned long arg)
376{
377 struct qfq_sched *q = qdisc_priv(sch);
378 struct qfq_class *cl = (struct qfq_class *)arg;
379
380 if (cl->filter_cnt > 0)
381 return -EBUSY;
382
383 sch_tree_lock(sch);
384
385 qfq_purge_queue(cl);
386 qdisc_class_hash_remove(&q->clhash, &cl->common);
387
388 BUG_ON(--cl->refcnt == 0);
389
390
391
392
393
394 sch_tree_unlock(sch);
395 return 0;
396}
397
398static unsigned long qfq_get_class(struct Qdisc *sch, u32 classid)
399{
400 struct qfq_class *cl = qfq_find_class(sch, classid);
401
402 if (cl != NULL)
403 cl->refcnt++;
404
405 return (unsigned long)cl;
406}
407
408static void qfq_put_class(struct Qdisc *sch, unsigned long arg)
409{
410 struct qfq_class *cl = (struct qfq_class *)arg;
411
412 if (--cl->refcnt == 0)
413 qfq_destroy_class(sch, cl);
414}
415
416static struct tcf_proto **qfq_tcf_chain(struct Qdisc *sch, unsigned long cl)
417{
418 struct qfq_sched *q = qdisc_priv(sch);
419
420 if (cl)
421 return NULL;
422
423 return &q->filter_list;
424}
425
426static unsigned long qfq_bind_tcf(struct Qdisc *sch, unsigned long parent,
427 u32 classid)
428{
429 struct qfq_class *cl = qfq_find_class(sch, classid);
430
431 if (cl != NULL)
432 cl->filter_cnt++;
433
434 return (unsigned long)cl;
435}
436
437static void qfq_unbind_tcf(struct Qdisc *sch, unsigned long arg)
438{
439 struct qfq_class *cl = (struct qfq_class *)arg;
440
441 cl->filter_cnt--;
442}
443
444static int qfq_graft_class(struct Qdisc *sch, unsigned long arg,
445 struct Qdisc *new, struct Qdisc **old)
446{
447 struct qfq_class *cl = (struct qfq_class *)arg;
448
449 if (new == NULL) {
450 new = qdisc_create_dflt(sch->dev_queue,
451 &pfifo_qdisc_ops, cl->common.classid);
452 if (new == NULL)
453 new = &noop_qdisc;
454 }
455
456 sch_tree_lock(sch);
457 qfq_purge_queue(cl);
458 *old = cl->qdisc;
459 cl->qdisc = new;
460 sch_tree_unlock(sch);
461 return 0;
462}
463
464static struct Qdisc *qfq_class_leaf(struct Qdisc *sch, unsigned long arg)
465{
466 struct qfq_class *cl = (struct qfq_class *)arg;
467
468 return cl->qdisc;
469}
470
471static int qfq_dump_class(struct Qdisc *sch, unsigned long arg,
472 struct sk_buff *skb, struct tcmsg *tcm)
473{
474 struct qfq_class *cl = (struct qfq_class *)arg;
475 struct nlattr *nest;
476
477 tcm->tcm_parent = TC_H_ROOT;
478 tcm->tcm_handle = cl->common.classid;
479 tcm->tcm_info = cl->qdisc->handle;
480
481 nest = nla_nest_start(skb, TCA_OPTIONS);
482 if (nest == NULL)
483 goto nla_put_failure;
484 if (nla_put_u32(skb, TCA_QFQ_WEIGHT, ONE_FP/cl->inv_w) ||
485 nla_put_u32(skb, TCA_QFQ_LMAX, cl->lmax))
486 goto nla_put_failure;
487 return nla_nest_end(skb, nest);
488
489nla_put_failure:
490 nla_nest_cancel(skb, nest);
491 return -EMSGSIZE;
492}
493
494static int qfq_dump_class_stats(struct Qdisc *sch, unsigned long arg,
495 struct gnet_dump *d)
496{
497 struct qfq_class *cl = (struct qfq_class *)arg;
498 struct tc_qfq_stats xstats;
499
500 memset(&xstats, 0, sizeof(xstats));
501 cl->qdisc->qstats.qlen = cl->qdisc->q.qlen;
502
503 xstats.weight = ONE_FP/cl->inv_w;
504 xstats.lmax = cl->lmax;
505
506 if (gnet_stats_copy_basic(d, &cl->bstats) < 0 ||
507 gnet_stats_copy_rate_est(d, &cl->bstats, &cl->rate_est) < 0 ||
508 gnet_stats_copy_queue(d, &cl->qdisc->qstats) < 0)
509 return -1;
510
511 return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
512}
513
514static void qfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
515{
516 struct qfq_sched *q = qdisc_priv(sch);
517 struct qfq_class *cl;
518 struct hlist_node *n;
519 unsigned int i;
520
521 if (arg->stop)
522 return;
523
524 for (i = 0; i < q->clhash.hashsize; i++) {
525 hlist_for_each_entry(cl, n, &q->clhash.hash[i], common.hnode) {
526 if (arg->count < arg->skip) {
527 arg->count++;
528 continue;
529 }
530 if (arg->fn(sch, (unsigned long)cl, arg) < 0) {
531 arg->stop = 1;
532 return;
533 }
534 arg->count++;
535 }
536 }
537}
538
539static struct qfq_class *qfq_classify(struct sk_buff *skb, struct Qdisc *sch,
540 int *qerr)
541{
542 struct qfq_sched *q = qdisc_priv(sch);
543 struct qfq_class *cl;
544 struct tcf_result res;
545 int result;
546
547 if (TC_H_MAJ(skb->priority ^ sch->handle) == 0) {
548 pr_debug("qfq_classify: found %d\n", skb->priority);
549 cl = qfq_find_class(sch, skb->priority);
550 if (cl != NULL)
551 return cl;
552 }
553
554 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
555 result = tc_classify(skb, q->filter_list, &res);
556 if (result >= 0) {
557#ifdef CONFIG_NET_CLS_ACT
558 switch (result) {
559 case TC_ACT_QUEUED:
560 case TC_ACT_STOLEN:
561 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
562 case TC_ACT_SHOT:
563 return NULL;
564 }
565#endif
566 cl = (struct qfq_class *)res.class;
567 if (cl == NULL)
568 cl = qfq_find_class(sch, res.classid);
569 return cl;
570 }
571
572 return NULL;
573}
574
575
576static inline int qfq_gt(u64 a, u64 b)
577{
578 return (s64)(a - b) > 0;
579}
580
581
582static inline u64 qfq_round_down(u64 ts, unsigned int shift)
583{
584 return ts & ~((1ULL << shift) - 1);
585}
586
587
588static inline struct qfq_group *qfq_ffs(struct qfq_sched *q,
589 unsigned long bitmap)
590{
591 int index = __ffs(bitmap);
592 return &q->groups[index];
593}
594
595static inline unsigned long mask_from(unsigned long bitmap, int from)
596{
597 return bitmap & ~((1UL << from) - 1);
598}
599
600
601
602
603
604
605static int qfq_calc_state(struct qfq_sched *q, const struct qfq_group *grp)
606{
607
608 unsigned int state = qfq_gt(grp->S, q->V);
609 unsigned long mask = mask_from(q->bitmaps[ER], grp->index);
610 struct qfq_group *next;
611
612 if (mask) {
613 next = qfq_ffs(q, mask);
614 if (qfq_gt(grp->F, next->F))
615 state |= EB;
616 }
617
618 return state;
619}
620
621
622
623
624
625
626
627
628static inline void qfq_move_groups(struct qfq_sched *q, unsigned long mask,
629 int src, int dst)
630{
631 q->bitmaps[dst] |= q->bitmaps[src] & mask;
632 q->bitmaps[src] &= ~mask;
633}
634
635static void qfq_unblock_groups(struct qfq_sched *q, int index, u64 old_F)
636{
637 unsigned long mask = mask_from(q->bitmaps[ER], index + 1);
638 struct qfq_group *next;
639
640 if (mask) {
641 next = qfq_ffs(q, mask);
642 if (!qfq_gt(next->F, old_F))
643 return;
644 }
645
646 mask = (1UL << index) - 1;
647 qfq_move_groups(q, mask, EB, ER);
648 qfq_move_groups(q, mask, IB, IR);
649}
650
651
652
653
654
655
656
657
658
659
660
661static void qfq_make_eligible(struct qfq_sched *q, u64 old_V)
662{
663 unsigned long vslot = q->V >> QFQ_MIN_SLOT_SHIFT;
664 unsigned long old_vslot = old_V >> QFQ_MIN_SLOT_SHIFT;
665
666 if (vslot != old_vslot) {
667 unsigned long mask = (1UL << fls(vslot ^ old_vslot)) - 1;
668 qfq_move_groups(q, mask, IR, ER);
669 qfq_move_groups(q, mask, IB, EB);
670 }
671}
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702static void qfq_slot_insert(struct qfq_group *grp, struct qfq_class *cl,
703 u64 roundedS)
704{
705 u64 slot = (roundedS - grp->S) >> grp->slot_shift;
706 unsigned int i;
707
708 if (unlikely(slot > QFQ_MAX_SLOTS - 2)) {
709 u64 deltaS = roundedS - grp->S -
710 ((u64)(QFQ_MAX_SLOTS - 2)<<grp->slot_shift);
711 cl->S -= deltaS;
712 cl->F -= deltaS;
713 slot = QFQ_MAX_SLOTS - 2;
714 }
715
716 i = (grp->front + slot) % QFQ_MAX_SLOTS;
717
718 hlist_add_head(&cl->next, &grp->slots[i]);
719 __set_bit(slot, &grp->full_slots);
720}
721
722
723static struct qfq_class *qfq_slot_head(struct qfq_group *grp)
724{
725 return hlist_entry(grp->slots[grp->front].first,
726 struct qfq_class, next);
727}
728
729
730
731
732static void qfq_front_slot_remove(struct qfq_group *grp)
733{
734 struct qfq_class *cl = qfq_slot_head(grp);
735
736 BUG_ON(!cl);
737 hlist_del(&cl->next);
738 if (hlist_empty(&grp->slots[grp->front]))
739 __clear_bit(0, &grp->full_slots);
740}
741
742
743
744
745
746
747static struct qfq_class *qfq_slot_scan(struct qfq_group *grp)
748{
749 unsigned int i;
750
751 pr_debug("qfq slot_scan: grp %u full %#lx\n",
752 grp->index, grp->full_slots);
753
754 if (grp->full_slots == 0)
755 return NULL;
756
757 i = __ffs(grp->full_slots);
758 if (i > 0) {
759 grp->front = (grp->front + i) % QFQ_MAX_SLOTS;
760 grp->full_slots >>= i;
761 }
762
763 return qfq_slot_head(grp);
764}
765
766
767
768
769
770
771
772
773
774
775static void qfq_slot_rotate(struct qfq_group *grp, u64 roundedS)
776{
777 unsigned int i = (grp->S - roundedS) >> grp->slot_shift;
778
779 grp->full_slots <<= i;
780 grp->front = (grp->front - i) % QFQ_MAX_SLOTS;
781}
782
783static void qfq_update_eligible(struct qfq_sched *q, u64 old_V)
784{
785 struct qfq_group *grp;
786 unsigned long ineligible;
787
788 ineligible = q->bitmaps[IR] | q->bitmaps[IB];
789 if (ineligible) {
790 if (!q->bitmaps[ER]) {
791 grp = qfq_ffs(q, ineligible);
792 if (qfq_gt(grp->S, q->V))
793 q->V = grp->S;
794 }
795 qfq_make_eligible(q, old_V);
796 }
797}
798
799
800
801
802static bool qfq_update_class(struct qfq_group *grp, struct qfq_class *cl)
803{
804 unsigned int len = qdisc_peek_len(cl->qdisc);
805
806 cl->S = cl->F;
807 if (!len)
808 qfq_front_slot_remove(grp);
809 else {
810 u64 roundedS;
811
812 cl->F = cl->S + (u64)len * cl->inv_w;
813 roundedS = qfq_round_down(cl->S, grp->slot_shift);
814 if (roundedS == grp->S)
815 return false;
816
817 qfq_front_slot_remove(grp);
818 qfq_slot_insert(grp, cl, roundedS);
819 }
820
821 return true;
822}
823
824static struct sk_buff *qfq_dequeue(struct Qdisc *sch)
825{
826 struct qfq_sched *q = qdisc_priv(sch);
827 struct qfq_group *grp;
828 struct qfq_class *cl;
829 struct sk_buff *skb;
830 unsigned int len;
831 u64 old_V;
832
833 if (!q->bitmaps[ER])
834 return NULL;
835
836 grp = qfq_ffs(q, q->bitmaps[ER]);
837
838 cl = qfq_slot_head(grp);
839 skb = qdisc_dequeue_peeked(cl->qdisc);
840 if (!skb) {
841 WARN_ONCE(1, "qfq_dequeue: non-workconserving leaf\n");
842 return NULL;
843 }
844
845 sch->q.qlen--;
846 qdisc_bstats_update(sch, skb);
847
848 old_V = q->V;
849 len = qdisc_pkt_len(skb);
850 q->V += (u64)len * IWSUM;
851 pr_debug("qfq dequeue: len %u F %lld now %lld\n",
852 len, (unsigned long long) cl->F, (unsigned long long) q->V);
853
854 if (qfq_update_class(grp, cl)) {
855 u64 old_F = grp->F;
856
857 cl = qfq_slot_scan(grp);
858 if (!cl)
859 __clear_bit(grp->index, &q->bitmaps[ER]);
860 else {
861 u64 roundedS = qfq_round_down(cl->S, grp->slot_shift);
862 unsigned int s;
863
864 if (grp->S == roundedS)
865 goto skip_unblock;
866 grp->S = roundedS;
867 grp->F = roundedS + (2ULL << grp->slot_shift);
868 __clear_bit(grp->index, &q->bitmaps[ER]);
869 s = qfq_calc_state(q, grp);
870 __set_bit(grp->index, &q->bitmaps[s]);
871 }
872
873 qfq_unblock_groups(q, grp->index, old_F);
874 }
875
876skip_unblock:
877 qfq_update_eligible(q, old_V);
878
879 return skb;
880}
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl)
896{
897 unsigned long mask;
898 u64 limit, roundedF;
899 int slot_shift = cl->grp->slot_shift;
900
901 roundedF = qfq_round_down(cl->F, slot_shift);
902 limit = qfq_round_down(q->V, slot_shift) + (1ULL << slot_shift);
903
904 if (!qfq_gt(cl->F, q->V) || qfq_gt(roundedF, limit)) {
905
906 mask = mask_from(q->bitmaps[ER], cl->grp->index);
907 if (mask) {
908 struct qfq_group *next = qfq_ffs(q, mask);
909 if (qfq_gt(roundedF, next->F)) {
910 if (qfq_gt(limit, next->F))
911 cl->S = next->F;
912 else
913 cl->S = limit;
914 return;
915 }
916 }
917 cl->S = q->V;
918 } else
919 cl->S = cl->F;
920}
921
922static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
923{
924 struct qfq_sched *q = qdisc_priv(sch);
925 struct qfq_class *cl;
926 int err = 0;
927
928 cl = qfq_classify(skb, sch, &err);
929 if (cl == NULL) {
930 if (err & __NET_XMIT_BYPASS)
931 sch->qstats.drops++;
932 kfree_skb(skb);
933 return err;
934 }
935 pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid);
936
937 if (unlikely(cl->lmax < qdisc_pkt_len(skb))) {
938 pr_debug("qfq: increasing maxpkt from %u to %u for class %u",
939 cl->lmax, qdisc_pkt_len(skb), cl->common.classid);
940 qfq_update_reactivate_class(q, cl, cl->inv_w,
941 qdisc_pkt_len(skb), 0);
942 }
943
944 err = qdisc_enqueue(skb, cl->qdisc);
945 if (unlikely(err != NET_XMIT_SUCCESS)) {
946 pr_debug("qfq_enqueue: enqueue failed %d\n", err);
947 if (net_xmit_drop_count(err)) {
948 cl->qstats.drops++;
949 sch->qstats.drops++;
950 }
951 return err;
952 }
953
954 bstats_update(&cl->bstats, skb);
955 ++sch->q.qlen;
956
957
958 if (cl->qdisc->q.qlen != 1)
959 return err;
960
961
962 qfq_activate_class(q, cl, qdisc_pkt_len(skb));
963
964 return err;
965}
966
967
968
969
970static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl,
971 unsigned int pkt_len)
972{
973 struct qfq_group *grp = cl->grp;
974 u64 roundedS;
975 int s;
976
977 qfq_update_start(q, cl);
978
979
980 cl->F = cl->S + (u64)pkt_len * cl->inv_w;
981 roundedS = qfq_round_down(cl->S, grp->slot_shift);
982
983
984
985
986
987
988
989
990
991
992 if (grp->full_slots) {
993 if (!qfq_gt(grp->S, cl->S))
994 goto skip_update;
995
996
997 qfq_slot_rotate(grp, roundedS);
998
999 __clear_bit(grp->index, &q->bitmaps[IR]);
1000 __clear_bit(grp->index, &q->bitmaps[IB]);
1001 } else if (!q->bitmaps[ER] && qfq_gt(roundedS, q->V))
1002 q->V = roundedS;
1003
1004 grp->S = roundedS;
1005 grp->F = roundedS + (2ULL << grp->slot_shift);
1006 s = qfq_calc_state(q, grp);
1007 __set_bit(grp->index, &q->bitmaps[s]);
1008
1009 pr_debug("qfq enqueue: new state %d %#lx S %lld F %lld V %lld\n",
1010 s, q->bitmaps[s],
1011 (unsigned long long) cl->S,
1012 (unsigned long long) cl->F,
1013 (unsigned long long) q->V);
1014
1015skip_update:
1016 qfq_slot_insert(grp, cl, roundedS);
1017}
1018
1019
1020static void qfq_slot_remove(struct qfq_sched *q, struct qfq_group *grp,
1021 struct qfq_class *cl)
1022{
1023 unsigned int i, offset;
1024 u64 roundedS;
1025
1026 roundedS = qfq_round_down(cl->S, grp->slot_shift);
1027 offset = (roundedS - grp->S) >> grp->slot_shift;
1028 i = (grp->front + offset) % QFQ_MAX_SLOTS;
1029
1030 hlist_del(&cl->next);
1031 if (hlist_empty(&grp->slots[i]))
1032 __clear_bit(offset, &grp->full_slots);
1033}
1034
1035
1036
1037
1038
1039
1040
1041
1042static void qfq_deactivate_class(struct qfq_sched *q, struct qfq_class *cl)
1043{
1044 struct qfq_group *grp = cl->grp;
1045 unsigned long mask;
1046 u64 roundedS;
1047 int s;
1048
1049 cl->F = cl->S;
1050 qfq_slot_remove(q, grp, cl);
1051
1052 if (!grp->full_slots) {
1053 __clear_bit(grp->index, &q->bitmaps[IR]);
1054 __clear_bit(grp->index, &q->bitmaps[EB]);
1055 __clear_bit(grp->index, &q->bitmaps[IB]);
1056
1057 if (test_bit(grp->index, &q->bitmaps[ER]) &&
1058 !(q->bitmaps[ER] & ~((1UL << grp->index) - 1))) {
1059 mask = q->bitmaps[ER] & ((1UL << grp->index) - 1);
1060 if (mask)
1061 mask = ~((1UL << __fls(mask)) - 1);
1062 else
1063 mask = ~0UL;
1064 qfq_move_groups(q, mask, EB, ER);
1065 qfq_move_groups(q, mask, IB, IR);
1066 }
1067 __clear_bit(grp->index, &q->bitmaps[ER]);
1068 } else if (hlist_empty(&grp->slots[grp->front])) {
1069 cl = qfq_slot_scan(grp);
1070 roundedS = qfq_round_down(cl->S, grp->slot_shift);
1071 if (grp->S != roundedS) {
1072 __clear_bit(grp->index, &q->bitmaps[ER]);
1073 __clear_bit(grp->index, &q->bitmaps[IR]);
1074 __clear_bit(grp->index, &q->bitmaps[EB]);
1075 __clear_bit(grp->index, &q->bitmaps[IB]);
1076 grp->S = roundedS;
1077 grp->F = roundedS + (2ULL << grp->slot_shift);
1078 s = qfq_calc_state(q, grp);
1079 __set_bit(grp->index, &q->bitmaps[s]);
1080 }
1081 }
1082
1083 qfq_update_eligible(q, q->V);
1084}
1085
1086static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg)
1087{
1088 struct qfq_sched *q = qdisc_priv(sch);
1089 struct qfq_class *cl = (struct qfq_class *)arg;
1090
1091 if (cl->qdisc->q.qlen == 0)
1092 qfq_deactivate_class(q, cl);
1093}
1094
1095static unsigned int qfq_drop(struct Qdisc *sch)
1096{
1097 struct qfq_sched *q = qdisc_priv(sch);
1098 struct qfq_group *grp;
1099 unsigned int i, j, len;
1100
1101 for (i = 0; i <= QFQ_MAX_INDEX; i++) {
1102 grp = &q->groups[i];
1103 for (j = 0; j < QFQ_MAX_SLOTS; j++) {
1104 struct qfq_class *cl;
1105 struct hlist_node *n;
1106
1107 hlist_for_each_entry(cl, n, &grp->slots[j], next) {
1108
1109 if (!cl->qdisc->ops->drop)
1110 continue;
1111
1112 len = cl->qdisc->ops->drop(cl->qdisc);
1113 if (len > 0) {
1114 sch->q.qlen--;
1115 if (!cl->qdisc->q.qlen)
1116 qfq_deactivate_class(q, cl);
1117
1118 return len;
1119 }
1120 }
1121 }
1122 }
1123
1124 return 0;
1125}
1126
1127static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
1128{
1129 struct qfq_sched *q = qdisc_priv(sch);
1130 struct qfq_group *grp;
1131 int i, j, err;
1132
1133 err = qdisc_class_hash_init(&q->clhash);
1134 if (err < 0)
1135 return err;
1136
1137 for (i = 0; i <= QFQ_MAX_INDEX; i++) {
1138 grp = &q->groups[i];
1139 grp->index = i;
1140 grp->slot_shift = QFQ_MTU_SHIFT + FRAC_BITS
1141 - (QFQ_MAX_INDEX - i);
1142 for (j = 0; j < QFQ_MAX_SLOTS; j++)
1143 INIT_HLIST_HEAD(&grp->slots[j]);
1144 }
1145
1146 return 0;
1147}
1148
1149static void qfq_reset_qdisc(struct Qdisc *sch)
1150{
1151 struct qfq_sched *q = qdisc_priv(sch);
1152 struct qfq_group *grp;
1153 struct qfq_class *cl;
1154 struct hlist_node *n, *tmp;
1155 unsigned int i, j;
1156
1157 for (i = 0; i <= QFQ_MAX_INDEX; i++) {
1158 grp = &q->groups[i];
1159 for (j = 0; j < QFQ_MAX_SLOTS; j++) {
1160 hlist_for_each_entry_safe(cl, n, tmp,
1161 &grp->slots[j], next) {
1162 qfq_deactivate_class(q, cl);
1163 }
1164 }
1165 }
1166
1167 for (i = 0; i < q->clhash.hashsize; i++) {
1168 hlist_for_each_entry(cl, n, &q->clhash.hash[i], common.hnode)
1169 qdisc_reset(cl->qdisc);
1170 }
1171 sch->q.qlen = 0;
1172}
1173
1174static void qfq_destroy_qdisc(struct Qdisc *sch)
1175{
1176 struct qfq_sched *q = qdisc_priv(sch);
1177 struct qfq_class *cl;
1178 struct hlist_node *n, *next;
1179 unsigned int i;
1180
1181 tcf_destroy_chain(&q->filter_list);
1182
1183 for (i = 0; i < q->clhash.hashsize; i++) {
1184 hlist_for_each_entry_safe(cl, n, next, &q->clhash.hash[i],
1185 common.hnode) {
1186 qfq_destroy_class(sch, cl);
1187 }
1188 }
1189 qdisc_class_hash_destroy(&q->clhash);
1190}
1191
1192static const struct Qdisc_class_ops qfq_class_ops = {
1193 .change = qfq_change_class,
1194 .delete = qfq_delete_class,
1195 .get = qfq_get_class,
1196 .put = qfq_put_class,
1197 .tcf_chain = qfq_tcf_chain,
1198 .bind_tcf = qfq_bind_tcf,
1199 .unbind_tcf = qfq_unbind_tcf,
1200 .graft = qfq_graft_class,
1201 .leaf = qfq_class_leaf,
1202 .qlen_notify = qfq_qlen_notify,
1203 .dump = qfq_dump_class,
1204 .dump_stats = qfq_dump_class_stats,
1205 .walk = qfq_walk,
1206};
1207
1208static struct Qdisc_ops qfq_qdisc_ops __read_mostly = {
1209 .cl_ops = &qfq_class_ops,
1210 .id = "qfq",
1211 .priv_size = sizeof(struct qfq_sched),
1212 .enqueue = qfq_enqueue,
1213 .dequeue = qfq_dequeue,
1214 .peek = qdisc_peek_dequeued,
1215 .drop = qfq_drop,
1216 .init = qfq_init_qdisc,
1217 .reset = qfq_reset_qdisc,
1218 .destroy = qfq_destroy_qdisc,
1219 .owner = THIS_MODULE,
1220};
1221
1222static int __init qfq_init(void)
1223{
1224 return register_qdisc(&qfq_qdisc_ops);
1225}
1226
1227static void __exit qfq_exit(void)
1228{
1229 unregister_qdisc(&qfq_qdisc_ops);
1230}
1231
1232module_init(qfq_init);
1233module_exit(qfq_exit);
1234MODULE_LICENSE("GPL");
1235