11 #include <linux/module.h>
13 #include <linux/bitops.h>
14 #include <linux/errno.h>
15 #include <linux/netdevice.h>
76 #define QFQ_MAX_SLOTS 32
87 #define QFQ_MAX_INDEX 24
88 #define QFQ_MAX_WSHIFT 12
90 #define QFQ_MAX_WEIGHT (1<<QFQ_MAX_WSHIFT)
91 #define QFQ_MAX_WSUM (16*QFQ_MAX_WEIGHT)
94 #define ONE_FP (1UL << FRAC_BITS)
95 #define IWSUM (ONE_FP/QFQ_MAX_WSUM)
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
161 clc = qdisc_class_find(&q->
clhash, classid);
169 unsigned int len = cl->
qdisc->q.qlen;
185 static int qfq_calc_index(
u32 inv_w,
unsigned int maxlen)
187 u64 slot_size = (
u64)maxlen * inv_w;
188 unsigned long size_map;
195 index =
__fls(size_map) + 1;
196 index -= !(slot_size - (1ULL << (index + QFQ_MIN_SLOT_SHIFT - 1)));
201 pr_debug(
"qfq calc_index: W = %lu, L = %u, I = %d\n",
202 (
unsigned long)
ONE_FP/inv_w, maxlen, index);
208 static unsigned int qdisc_peek_len(
struct Qdisc *sch)
212 skb = sch->
ops->peek(sch);
213 return skb ? qdisc_pkt_len(skb) : 0;
221 u32 lmax,
u32 inv_w,
int delta_w)
235 static void qfq_update_reactivate_class(
struct qfq_sched *q,
237 u32 inv_w,
u32 lmax,
int delta_w)
239 bool need_reactivation =
false;
240 int i = qfq_calc_index(inv_w, lmax);
250 qfq_deactivate_class(q, cl);
251 need_reactivation =
true;
254 qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
256 if (need_reactivation)
257 qfq_activate_class(q, cl, qdisc_peek_len(cl->
qdisc));
261 static int qfq_change_class(
struct Qdisc *sch,
u32 classid,
u32 parentid,
281 weight = nla_get_u32(tb[TCA_QFQ_WEIGHT]);
283 pr_notice(
"qfq: invalid weight %u\n", weight);
293 pr_notice(
"qfq: total weight out of range (%u + %u)\n",
299 lmax = nla_get_u32(tb[TCA_QFQ_LMAX]);
301 pr_notice(
"qfq: invalid max length %u\n", lmax);
305 lmax = psched_mtu(qdisc_dev(sch));
310 qdisc_root_sleeping_lock(sch),
316 if (lmax == cl->
lmax && inv_w == cl->
inv_w)
320 qfq_update_reactivate_class(q, cl, inv_w, lmax, delta_w);
321 sch_tree_unlock(sch);
331 cl->
common.classid = classid;
333 qfq_update_class_params(q, cl, lmax, inv_w, delta_w);
336 &pfifo_qdisc_ops, classid);
342 qdisc_root_sleeping_lock(sch),
353 sch_tree_unlock(sch);
357 *arg = (
unsigned long)cl;
361 static void qfq_destroy_class(
struct Qdisc *sch,
struct qfq_class *cl)
375 static int qfq_delete_class(
struct Qdisc *sch,
unsigned long arg)
394 sch_tree_unlock(sch);
398 static unsigned long qfq_get_class(
struct Qdisc *sch,
u32 classid)
400 struct qfq_class *cl = qfq_find_class(sch, classid);
405 return (
unsigned long)
cl;
408 static void qfq_put_class(
struct Qdisc *sch,
unsigned long arg)
413 qfq_destroy_class(sch, cl);
416 static struct tcf_proto **qfq_tcf_chain(
struct Qdisc *sch,
unsigned long cl)
426 static unsigned long qfq_bind_tcf(
struct Qdisc *sch,
unsigned long parent,
429 struct qfq_class *cl = qfq_find_class(sch, classid);
434 return (
unsigned long)
cl;
437 static void qfq_unbind_tcf(
struct Qdisc *sch,
unsigned long arg)
444 static int qfq_graft_class(
struct Qdisc *sch,
unsigned long arg,
451 &pfifo_qdisc_ops, cl->
common.classid);
460 sch_tree_unlock(sch);
464 static struct Qdisc *qfq_class_leaf(
struct Qdisc *sch,
unsigned long arg)
471 static int qfq_dump_class(
struct Qdisc *sch,
unsigned long arg,
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);
490 nla_nest_cancel(skb, nest);
494 static int qfq_dump_class_stats(
struct Qdisc *sch,
unsigned long arg,
500 memset(&xstats, 0,
sizeof(xstats));
504 xstats.lmax = cl->
lmax;
524 for (i = 0; i < q->
clhash.hashsize; i++) {
530 if (arg->
fn(sch, (
unsigned long)cl, arg) < 0) {
549 cl = qfq_find_class(sch, skb->
priority);
557 #ifdef CONFIG_NET_CLS_ACT
568 cl = qfq_find_class(sch,
res.classid);
576 static inline int qfq_gt(
u64 a,
u64 b)
578 return (
s64)(a -
b) > 0;
582 static inline u64 qfq_round_down(
u64 ts,
unsigned int shift)
584 return ts & ~((1ULL << shift) - 1);
591 int index =
__ffs(bitmap);
595 static inline unsigned long mask_from(
unsigned long bitmap,
int from)
597 return bitmap & ~((1
UL <<
from) - 1);
608 unsigned int state = qfq_gt(grp->
S, q->
V);
613 next = qfq_ffs(q, mask);
614 if (qfq_gt(grp->
F, next->
F))
628 static inline void qfq_move_groups(
struct qfq_sched *q,
unsigned long mask,
635 static void qfq_unblock_groups(
struct qfq_sched *q,
int index,
u64 old_F)
637 unsigned long mask = mask_from(q->
bitmaps[
ER], index + 1);
641 next = qfq_ffs(q, mask);
642 if (!qfq_gt(next->
F, old_F))
647 qfq_move_groups(q, mask,
EB,
ER);
648 qfq_move_groups(q, mask,
IB,
IR);
661 static void qfq_make_eligible(
struct qfq_sched *q,
u64 old_V)
666 if (vslot != old_vslot) {
667 unsigned long mask = (1
UL << fls(vslot ^ old_vslot)) - 1;
668 qfq_move_groups(q, mask,
IR,
ER);
669 qfq_move_groups(q, mask,
IB,
EB);
709 u64 deltaS = roundedS - grp->
S -
718 hlist_add_head(&cl->
next, &grp->
slots[i]);
732 static void qfq_front_slot_remove(
struct qfq_group *grp)
734 struct qfq_class *cl = qfq_slot_head(grp);
737 hlist_del(&cl->
next);
751 pr_debug(
"qfq slot_scan: grp %u full %#lx\n",
763 return qfq_slot_head(grp);
775 static void qfq_slot_rotate(
struct qfq_group *grp,
u64 roundedS)
777 unsigned int i = (grp->
S - roundedS) >> grp->
slot_shift;
783 static void qfq_update_eligible(
struct qfq_sched *q,
u64 old_V)
786 unsigned long ineligible;
791 grp = qfq_ffs(q, ineligible);
792 if (qfq_gt(grp->
S, q->
V))
795 qfq_make_eligible(q, old_V);
804 unsigned int len = qdisc_peek_len(cl->
qdisc);
808 qfq_front_slot_remove(grp);
814 if (roundedS == grp->
S)
817 qfq_front_slot_remove(grp);
818 qfq_slot_insert(grp, cl, roundedS);
838 cl = qfq_slot_head(grp);
839 skb = qdisc_dequeue_peeked(cl->
qdisc);
841 WARN_ONCE(1,
"qfq_dequeue: non-workconserving leaf\n");
846 qdisc_bstats_update(sch, skb);
849 len = qdisc_pkt_len(skb);
851 pr_debug(
"qfq dequeue: len %u F %lld now %lld\n",
852 len, (
unsigned long long) cl->
F, (
unsigned long long) q->
V);
854 if (qfq_update_class(grp, cl)) {
857 cl = qfq_slot_scan(grp);
864 if (grp->
S == roundedS)
869 s = qfq_calc_state(q, grp);
873 qfq_unblock_groups(q, grp->
index, old_F);
877 qfq_update_eligible(q, old_V);
901 roundedF = qfq_round_down(cl->
F, slot_shift);
902 limit = qfq_round_down(q->
V, slot_shift) + (1ULL <<
slot_shift);
904 if (!qfq_gt(cl->
F, q->
V) || qfq_gt(roundedF, limit)) {
908 struct qfq_group *next = qfq_ffs(q, mask);
909 if (qfq_gt(roundedF, next->
F)) {
910 if (qfq_gt(limit, next->
F))
922 static int qfq_enqueue(
struct sk_buff *skb,
struct Qdisc *sch)
928 cl = qfq_classify(skb, sch, &err);
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);
944 err = qdisc_enqueue(skb, cl->
qdisc);
946 pr_debug(
"qfq_enqueue: enqueue failed %d\n", err);
954 bstats_update(&cl->
bstats, skb);
958 if (cl->
qdisc->q.qlen != 1)
962 qfq_activate_class(q, cl, qdisc_pkt_len(skb));
977 qfq_update_start(q, cl);
993 if (!qfq_gt(grp->
S, cl->
S))
997 qfq_slot_rotate(grp, roundedS);
1001 }
else if (!q->
bitmaps[
ER] && qfq_gt(roundedS, q->
V))
1006 s = qfq_calc_state(q, grp);
1009 pr_debug(
"qfq enqueue: new state %d %#lx S %lld F %lld V %lld\n",
1011 (
unsigned long long) cl->
S,
1012 (
unsigned long long) cl->
F,
1013 (
unsigned long long) q->
V);
1016 qfq_slot_insert(grp, cl, roundedS);
1026 roundedS = qfq_round_down(cl->
S, grp->
slot_shift);
1030 hlist_del(&cl->
next);
1031 if (hlist_empty(&grp->
slots[i]))
1050 qfq_slot_remove(q, grp, cl);
1061 mask = ~((1
UL <<
__fls(mask)) - 1);
1064 qfq_move_groups(q, mask,
EB,
ER);
1065 qfq_move_groups(q, mask,
IB,
IR);
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) {
1078 s = qfq_calc_state(q, grp);
1083 qfq_update_eligible(q, q->
V);
1086 static void qfq_qlen_notify(
struct Qdisc *sch,
unsigned long arg)
1091 if (cl->
qdisc->q.qlen == 0)
1092 qfq_deactivate_class(q, cl);
1095 static unsigned int qfq_drop(
struct Qdisc *sch)
1099 unsigned int i,
j, len;
1109 if (!cl->
qdisc->ops->drop)
1115 if (!cl->
qdisc->q.qlen)
1116 qfq_deactivate_class(q, cl);
1149 static void qfq_reset_qdisc(
struct Qdisc *sch)
1161 &grp->
slots[j], next) {
1162 qfq_deactivate_class(q, cl);
1167 for (i = 0; i < q->
clhash.hashsize; i++) {
1183 for (i = 0; i < q->
clhash.hashsize; i++) {
1186 qfq_destroy_class(sch, cl);
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,
1209 .cl_ops = &qfq_class_ops,
1212 .enqueue = qfq_enqueue,
1213 .dequeue = qfq_dequeue,
1214 .peek = qdisc_peek_dequeued,
1216 .init = qfq_init_qdisc,
1217 .reset = qfq_reset_qdisc,
1218 .destroy = qfq_destroy_qdisc,
1222 static int __init qfq_init(
void)
1227 static void __exit qfq_exit(
void)