]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - net/sched/sch_sfq.c
Merge tag 'mmc-v4.15-2' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
[mirror_ubuntu-bionic-kernel.git] / net / sched / sch_sfq.c
CommitLineData
1da177e4
LT
1/*
2 * net/sched/sch_sfq.c Stochastic Fairness Queueing discipline.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10 */
11
1da177e4 12#include <linux/module.h>
1da177e4
LT
13#include <linux/types.h>
14#include <linux/kernel.h>
15#include <linux/jiffies.h>
16#include <linux/string.h>
1da177e4
LT
17#include <linux/in.h>
18#include <linux/errno.h>
1da177e4 19#include <linux/init.h>
1da177e4 20#include <linux/skbuff.h>
32740ddc 21#include <linux/jhash.h>
5a0e3ad6 22#include <linux/slab.h>
817fb15d 23#include <linux/vmalloc.h>
0ba48053 24#include <net/netlink.h>
1da177e4 25#include <net/pkt_sched.h>
cf1facda 26#include <net/pkt_cls.h>
ddecf0f4 27#include <net/red.h>
1da177e4
LT
28
29
30/* Stochastic Fairness Queuing algorithm.
31 =======================================
32
33 Source:
34 Paul E. McKenney "Stochastic Fairness Queuing",
35 IEEE INFOCOMM'90 Proceedings, San Francisco, 1990.
36
37 Paul E. McKenney "Stochastic Fairness Queuing",
38 "Interworking: Research and Experience", v.2, 1991, p.113-131.
39
40
41 See also:
42 M. Shreedhar and George Varghese "Efficient Fair
43 Queuing using Deficit Round Robin", Proc. SIGCOMM 95.
44
45
10297b99 46 This is not the thing that is usually called (W)FQ nowadays.
1da177e4
LT
47 It does not use any timestamp mechanism, but instead
48 processes queues in round-robin order.
49
50 ADVANTAGE:
51
52 - It is very cheap. Both CPU and memory requirements are minimal.
53
54 DRAWBACKS:
55
10297b99 56 - "Stochastic" -> It is not 100% fair.
1da177e4
LT
57 When hash collisions occur, several flows are considered as one.
58
59 - "Round-robin" -> It introduces larger delays than virtual clock
60 based schemes, and should not be used for isolating interactive
61 traffic from non-interactive. It means, that this scheduler
62 should be used as leaf of CBQ or P3, which put interactive traffic
63 to higher priority band.
64
65 We still need true WFQ for top level CSZ, but using WFQ
66 for the best effort traffic is absolutely pointless:
67 SFQ is superior for this purpose.
68
69 IMPLEMENTATION:
18cb8098
ED
70 This implementation limits :
71 - maximal queue length per flow to 127 packets.
72 - max mtu to 2^18-1;
73 - max 65408 flows,
74 - number of hash buckets to 65536.
1da177e4
LT
75
76 It is easy to increase these values, but not in flight. */
77
18cb8098
ED
78#define SFQ_MAX_DEPTH 127 /* max number of packets per flow */
79#define SFQ_DEFAULT_FLOWS 128
80#define SFQ_MAX_FLOWS (0x10000 - SFQ_MAX_DEPTH - 1) /* max number of flows */
81#define SFQ_EMPTY_SLOT 0xffff
817fb15d
ED
82#define SFQ_DEFAULT_HASH_DIVISOR 1024
83
eeaeb068
ED
84/* We use 16 bits to store allot, and want to handle packets up to 64K
85 * Scale allot by 8 (1<<3) so that no overflow occurs.
86 */
87#define SFQ_ALLOT_SHIFT 3
88#define SFQ_ALLOT_SIZE(X) DIV_ROUND_UP(X, 1 << SFQ_ALLOT_SHIFT)
1da177e4 89
18cb8098
ED
90/* This type should contain at least SFQ_MAX_DEPTH + 1 + SFQ_MAX_FLOWS values */
91typedef u16 sfq_index;
1da177e4 92
eda83e3b
ED
93/*
94 * We dont use pointers to save space.
18cb8098
ED
95 * Small indexes [0 ... SFQ_MAX_FLOWS - 1] are 'pointers' to slots[] array
96 * while following values [SFQ_MAX_FLOWS ... SFQ_MAX_FLOWS + SFQ_MAX_DEPTH]
eda83e3b
ED
97 * are 'pointers' to dep[] array
98 */
cc7ec456 99struct sfq_head {
1da177e4
LT
100 sfq_index next;
101 sfq_index prev;
102};
103
eda83e3b
ED
104struct sfq_slot {
105 struct sk_buff *skblist_next;
106 struct sk_buff *skblist_prev;
107 sfq_index qlen; /* number of skbs in skblist */
18cb8098 108 sfq_index next; /* next slot in sfq RR chain */
eda83e3b
ED
109 struct sfq_head dep; /* anchor in dep[] chains */
110 unsigned short hash; /* hash value (index in ht[]) */
111 short allot; /* credit for this slot */
ddecf0f4
ED
112
113 unsigned int backlog;
114 struct red_vars vars;
eda83e3b
ED
115};
116
cc7ec456 117struct sfq_sched_data {
18cb8098
ED
118/* frequently used fields */
119 int limit; /* limit of total number of packets in this qdisc */
817fb15d 120 unsigned int divisor; /* number of slots in hash table */
ddecf0f4
ED
121 u8 headdrop;
122 u8 maxdepth; /* limit of packets per flow */
18cb8098 123
32740ddc 124 u32 perturbation;
ddecf0f4
ED
125 u8 cur_depth; /* depth of longest slot */
126 u8 flags;
eeaeb068 127 unsigned short scaled_quantum; /* SFQ_ALLOT_SIZE(quantum) */
25d8c0d5 128 struct tcf_proto __rcu *filter_list;
6529eaba 129 struct tcf_block *block;
18cb8098
ED
130 sfq_index *ht; /* Hash table ('divisor' slots) */
131 struct sfq_slot *slots; /* Flows table ('maxflows' entries) */
132
ddecf0f4
ED
133 struct red_parms *red_parms;
134 struct tc_sfqred_stats stats;
135 struct sfq_slot *tail; /* current slot in round */
136
18cb8098
ED
137 struct sfq_head dep[SFQ_MAX_DEPTH + 1];
138 /* Linked lists of slots, indexed by depth
139 * dep[0] : list of unused flows
140 * dep[1] : list of flows with 1 packet
141 * dep[X] : list of flows with X packets
142 */
143
ddecf0f4 144 unsigned int maxflows; /* number of flows in flows array */
18cb8098
ED
145 int perturb_period;
146 unsigned int quantum; /* Allotment per round: MUST BE >= MTU */
147 struct timer_list perturb_timer;
cdeabbb8 148 struct Qdisc *sch;
1da177e4
LT
149};
150
eda83e3b
ED
151/*
152 * sfq_head are either in a sfq_slot or in dep[] array
153 */
154static inline struct sfq_head *sfq_dep_head(struct sfq_sched_data *q, sfq_index val)
155{
18cb8098 156 if (val < SFQ_MAX_FLOWS)
eda83e3b 157 return &q->slots[val].dep;
18cb8098 158 return &q->dep[val - SFQ_MAX_FLOWS];
eda83e3b
ED
159}
160
11fca931
ED
161static unsigned int sfq_hash(const struct sfq_sched_data *q,
162 const struct sk_buff *skb)
1da177e4 163{
ada1dba0 164 return skb_get_hash_perturb(skb, q->perturbation) & (q->divisor - 1);
1da177e4
LT
165}
166
7d2681a6
PM
167static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
168 int *qerr)
169{
170 struct sfq_sched_data *q = qdisc_priv(sch);
171 struct tcf_result res;
25d8c0d5 172 struct tcf_proto *fl;
7d2681a6
PM
173 int result;
174
175 if (TC_H_MAJ(skb->priority) == sch->handle &&
176 TC_H_MIN(skb->priority) > 0 &&
817fb15d 177 TC_H_MIN(skb->priority) <= q->divisor)
7d2681a6
PM
178 return TC_H_MIN(skb->priority);
179
25d8c0d5 180 fl = rcu_dereference_bh(q->filter_list);
ada1dba0 181 if (!fl)
7d2681a6
PM
182 return sfq_hash(q, skb) + 1;
183
c27f339a 184 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
87d83093 185 result = tcf_classify(skb, fl, &res, false);
7d2681a6
PM
186 if (result >= 0) {
187#ifdef CONFIG_NET_CLS_ACT
188 switch (result) {
189 case TC_ACT_STOLEN:
190 case TC_ACT_QUEUED:
e25ea21f 191 case TC_ACT_TRAP:
378a2f09 192 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
f3ae608e 193 /* fall through */
7d2681a6
PM
194 case TC_ACT_SHOT:
195 return 0;
196 }
197#endif
817fb15d 198 if (TC_H_MIN(res.classid) <= q->divisor)
7d2681a6
PM
199 return TC_H_MIN(res.classid);
200 }
201 return 0;
202}
203
eda83e3b 204/*
18cb8098 205 * x : slot number [0 .. SFQ_MAX_FLOWS - 1]
eda83e3b 206 */
1da177e4
LT
207static inline void sfq_link(struct sfq_sched_data *q, sfq_index x)
208{
209 sfq_index p, n;
18cb8098
ED
210 struct sfq_slot *slot = &q->slots[x];
211 int qlen = slot->qlen;
eda83e3b 212
18cb8098 213 p = qlen + SFQ_MAX_FLOWS;
eda83e3b 214 n = q->dep[qlen].next;
1da177e4 215
18cb8098
ED
216 slot->dep.next = n;
217 slot->dep.prev = p;
eda83e3b
ED
218
219 q->dep[qlen].next = x; /* sfq_dep_head(q, p)->next = x */
220 sfq_dep_head(q, n)->prev = x;
1da177e4
LT
221}
222
eda83e3b 223#define sfq_unlink(q, x, n, p) \
fa08943b
YY
224 do { \
225 n = q->slots[x].dep.next; \
226 p = q->slots[x].dep.prev; \
227 sfq_dep_head(q, p)->next = n; \
228 sfq_dep_head(q, n)->prev = p; \
229 } while (0)
eda83e3b
ED
230
231
1da177e4
LT
232static inline void sfq_dec(struct sfq_sched_data *q, sfq_index x)
233{
234 sfq_index p, n;
eda83e3b 235 int d;
1da177e4 236
eda83e3b 237 sfq_unlink(q, x, n, p);
1da177e4 238
eda83e3b
ED
239 d = q->slots[x].qlen--;
240 if (n == p && q->cur_depth == d)
241 q->cur_depth--;
1da177e4
LT
242 sfq_link(q, x);
243}
244
245static inline void sfq_inc(struct sfq_sched_data *q, sfq_index x)
246{
247 sfq_index p, n;
248 int d;
249
eda83e3b 250 sfq_unlink(q, x, n, p);
1da177e4 251
eda83e3b
ED
252 d = ++q->slots[x].qlen;
253 if (q->cur_depth < d)
254 q->cur_depth = d;
1da177e4
LT
255 sfq_link(q, x);
256}
257
eda83e3b
ED
258/* helper functions : might be changed when/if skb use a standard list_head */
259
260/* remove one skb from tail of slot queue */
261static inline struct sk_buff *slot_dequeue_tail(struct sfq_slot *slot)
262{
263 struct sk_buff *skb = slot->skblist_prev;
264
265 slot->skblist_prev = skb->prev;
ee09b3c1 266 skb->prev->next = (struct sk_buff *)slot;
eda83e3b
ED
267 skb->next = skb->prev = NULL;
268 return skb;
269}
270
271/* remove one skb from head of slot queue */
272static inline struct sk_buff *slot_dequeue_head(struct sfq_slot *slot)
273{
274 struct sk_buff *skb = slot->skblist_next;
275
276 slot->skblist_next = skb->next;
18c8d82a 277 skb->next->prev = (struct sk_buff *)slot;
eda83e3b
ED
278 skb->next = skb->prev = NULL;
279 return skb;
280}
281
282static inline void slot_queue_init(struct sfq_slot *slot)
283{
18cb8098 284 memset(slot, 0, sizeof(*slot));
eda83e3b
ED
285 slot->skblist_prev = slot->skblist_next = (struct sk_buff *)slot;
286}
287
288/* add skb to slot queue (tail add) */
289static inline void slot_queue_add(struct sfq_slot *slot, struct sk_buff *skb)
290{
291 skb->prev = slot->skblist_prev;
292 skb->next = (struct sk_buff *)slot;
293 slot->skblist_prev->next = skb;
294 slot->skblist_prev = skb;
295}
296
f9ab7425 297static unsigned int sfq_drop(struct Qdisc *sch, struct sk_buff **to_free)
1da177e4
LT
298{
299 struct sfq_sched_data *q = qdisc_priv(sch);
eda83e3b 300 sfq_index x, d = q->cur_depth;
1da177e4
LT
301 struct sk_buff *skb;
302 unsigned int len;
eda83e3b 303 struct sfq_slot *slot;
1da177e4 304
eda83e3b 305 /* Queue is full! Find the longest slot and drop tail packet from it */
1da177e4 306 if (d > 1) {
eda83e3b
ED
307 x = q->dep[d].next;
308 slot = &q->slots[x];
309drop:
18cb8098 310 skb = q->headdrop ? slot_dequeue_head(slot) : slot_dequeue_tail(slot);
0abf77e5 311 len = qdisc_pkt_len(skb);
ddecf0f4 312 slot->backlog -= len;
1da177e4
LT
313 sfq_dec(q, x);
314 sch->q.qlen--;
25331d6c 315 qdisc_qstats_backlog_dec(sch, skb);
f9ab7425 316 qdisc_drop(skb, sch, to_free);
1da177e4
LT
317 return len;
318 }
319
320 if (d == 1) {
321 /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
eda83e3b
ED
322 x = q->tail->next;
323 slot = &q->slots[x];
324 q->tail->next = slot->next;
325 q->ht[slot->hash] = SFQ_EMPTY_SLOT;
326 goto drop;
1da177e4
LT
327 }
328
329 return 0;
330}
331
ddecf0f4
ED
332/* Is ECN parameter configured */
333static int sfq_prob_mark(const struct sfq_sched_data *q)
334{
335 return q->flags & TC_RED_ECN;
336}
337
338/* Should packets over max threshold just be marked */
339static int sfq_hard_mark(const struct sfq_sched_data *q)
340{
341 return (q->flags & (TC_RED_ECN | TC_RED_HARDDROP)) == TC_RED_ECN;
342}
343
344static int sfq_headdrop(const struct sfq_sched_data *q)
345{
346 return q->headdrop;
347}
348
1da177e4 349static int
520ac30f 350sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)
1da177e4
LT
351{
352 struct sfq_sched_data *q = qdisc_priv(sch);
2ccccf5f 353 unsigned int hash, dropped;
8efa8854 354 sfq_index x, qlen;
eda83e3b 355 struct sfq_slot *slot;
7f3ff4f6 356 int uninitialized_var(ret);
ddecf0f4
ED
357 struct sk_buff *head;
358 int delta;
7d2681a6
PM
359
360 hash = sfq_classify(skb, sch, &ret);
361 if (hash == 0) {
c27f339a 362 if (ret & __NET_XMIT_BYPASS)
25331d6c 363 qdisc_qstats_drop(sch);
f9ab7425 364 __qdisc_drop(skb, to_free);
7d2681a6
PM
365 return ret;
366 }
367 hash--;
1da177e4
LT
368
369 x = q->ht[hash];
eda83e3b
ED
370 slot = &q->slots[x];
371 if (x == SFQ_EMPTY_SLOT) {
372 x = q->dep[0].next; /* get a free slot */
18cb8098 373 if (x >= SFQ_MAX_FLOWS)
520ac30f 374 return qdisc_drop(skb, sch, to_free);
eda83e3b
ED
375 q->ht[hash] = x;
376 slot = &q->slots[x];
377 slot->hash = hash;
ddecf0f4
ED
378 slot->backlog = 0; /* should already be 0 anyway... */
379 red_set_vars(&slot->vars);
380 goto enqueue;
381 }
382 if (q->red_parms) {
383 slot->vars.qavg = red_calc_qavg_no_idle_time(q->red_parms,
384 &slot->vars,
385 slot->backlog);
386 switch (red_action(q->red_parms,
387 &slot->vars,
388 slot->vars.qavg)) {
389 case RED_DONT_MARK:
390 break;
391
392 case RED_PROB_MARK:
25331d6c 393 qdisc_qstats_overlimit(sch);
ddecf0f4
ED
394 if (sfq_prob_mark(q)) {
395 /* We know we have at least one packet in queue */
396 if (sfq_headdrop(q) &&
397 INET_ECN_set_ce(slot->skblist_next)) {
398 q->stats.prob_mark_head++;
399 break;
400 }
401 if (INET_ECN_set_ce(skb)) {
402 q->stats.prob_mark++;
403 break;
404 }
405 }
406 q->stats.prob_drop++;
407 goto congestion_drop;
408
409 case RED_HARD_MARK:
25331d6c 410 qdisc_qstats_overlimit(sch);
ddecf0f4
ED
411 if (sfq_hard_mark(q)) {
412 /* We know we have at least one packet in queue */
413 if (sfq_headdrop(q) &&
414 INET_ECN_set_ce(slot->skblist_next)) {
415 q->stats.forced_mark_head++;
416 break;
417 }
418 if (INET_ECN_set_ce(skb)) {
419 q->stats.forced_mark++;
420 break;
421 }
422 }
423 q->stats.forced_drop++;
424 goto congestion_drop;
425 }
1da177e4 426 }
6f9e98f7 427
18cb8098 428 if (slot->qlen >= q->maxdepth) {
ddecf0f4
ED
429congestion_drop:
430 if (!sfq_headdrop(q))
520ac30f 431 return qdisc_drop(skb, sch, to_free);
18cb8098 432
ddecf0f4 433 /* We know we have at least one packet in queue */
18cb8098 434 head = slot_dequeue_head(slot);
ddecf0f4
ED
435 delta = qdisc_pkt_len(head) - qdisc_pkt_len(skb);
436 sch->qstats.backlog -= delta;
437 slot->backlog -= delta;
520ac30f 438 qdisc_drop(head, sch, to_free);
18cb8098 439
18cb8098 440 slot_queue_add(slot, skb);
325d5dc3 441 qdisc_tree_reduce_backlog(sch, 0, delta);
18cb8098
ED
442 return NET_XMIT_CN;
443 }
32740ddc 444
ddecf0f4 445enqueue:
25331d6c 446 qdisc_qstats_backlog_inc(sch, skb);
ddecf0f4 447 slot->backlog += qdisc_pkt_len(skb);
eda83e3b 448 slot_queue_add(slot, skb);
1da177e4 449 sfq_inc(q, x);
eda83e3b
ED
450 if (slot->qlen == 1) { /* The flow is new */
451 if (q->tail == NULL) { /* It is the first flow */
452 slot->next = x;
1da177e4 453 } else {
eda83e3b
ED
454 slot->next = q->tail->next;
455 q->tail->next = x;
1da177e4 456 }
cc34eb67
ED
457 /* We put this flow at the end of our flow list.
458 * This might sound unfair for a new flow to wait after old ones,
459 * but we could endup servicing new flows only, and freeze old ones.
460 */
461 q->tail = slot;
ddecf0f4 462 /* We could use a bigger initial quantum for new flows */
eeaeb068 463 slot->allot = q->scaled_quantum;
1da177e4 464 }
9190b3b3 465 if (++sch->q.qlen <= q->limit)
9871e50e 466 return NET_XMIT_SUCCESS;
1da177e4 467
8efa8854 468 qlen = slot->qlen;
f9ab7425 469 dropped = sfq_drop(sch, to_free);
8efa8854
ED
470 /* Return Congestion Notification only if we dropped a packet
471 * from this flow.
472 */
325d5dc3
KK
473 if (qlen != slot->qlen) {
474 qdisc_tree_reduce_backlog(sch, 0, dropped - qdisc_pkt_len(skb));
e1738bd9 475 return NET_XMIT_CN;
325d5dc3 476 }
e1738bd9
ED
477
478 /* As we dropped a packet, better let upper stack know this */
2ccccf5f 479 qdisc_tree_reduce_backlog(sch, 1, dropped);
e1738bd9 480 return NET_XMIT_SUCCESS;
1da177e4
LT
481}
482
1da177e4 483static struct sk_buff *
6f9e98f7 484sfq_dequeue(struct Qdisc *sch)
1da177e4
LT
485{
486 struct sfq_sched_data *q = qdisc_priv(sch);
487 struct sk_buff *skb;
aa3e2199 488 sfq_index a, next_a;
eda83e3b 489 struct sfq_slot *slot;
1da177e4
LT
490
491 /* No active slots */
eda83e3b 492 if (q->tail == NULL)
1da177e4
LT
493 return NULL;
494
eeaeb068 495next_slot:
eda83e3b
ED
496 a = q->tail->next;
497 slot = &q->slots[a];
eeaeb068
ED
498 if (slot->allot <= 0) {
499 q->tail = slot;
500 slot->allot += q->scaled_quantum;
501 goto next_slot;
502 }
eda83e3b 503 skb = slot_dequeue_head(slot);
1da177e4 504 sfq_dec(q, a);
9190b3b3 505 qdisc_bstats_update(sch, skb);
1da177e4 506 sch->q.qlen--;
25331d6c 507 qdisc_qstats_backlog_dec(sch, skb);
ddecf0f4 508 slot->backlog -= qdisc_pkt_len(skb);
1da177e4 509 /* Is the slot empty? */
eda83e3b
ED
510 if (slot->qlen == 0) {
511 q->ht[slot->hash] = SFQ_EMPTY_SLOT;
512 next_a = slot->next;
aa3e2199 513 if (a == next_a) {
eda83e3b 514 q->tail = NULL; /* no more active slots */
1da177e4
LT
515 return skb;
516 }
eda83e3b 517 q->tail->next = next_a;
eeaeb068
ED
518 } else {
519 slot->allot -= SFQ_ALLOT_SIZE(qdisc_pkt_len(skb));
1da177e4
LT
520 }
521 return skb;
522}
523
524static void
6f9e98f7 525sfq_reset(struct Qdisc *sch)
1da177e4
LT
526{
527 struct sk_buff *skb;
528
529 while ((skb = sfq_dequeue(sch)) != NULL)
fea02478 530 rtnl_kfree_skbs(skb, skb);
1da177e4
LT
531}
532
225d9b89
ED
533/*
534 * When q->perturbation is changed, we rehash all queued skbs
535 * to avoid OOO (Out Of Order) effects.
536 * We dont use sfq_dequeue()/sfq_enqueue() because we dont want to change
537 * counters.
538 */
18cb8098 539static void sfq_rehash(struct Qdisc *sch)
225d9b89 540{
18cb8098 541 struct sfq_sched_data *q = qdisc_priv(sch);
225d9b89
ED
542 struct sk_buff *skb;
543 int i;
544 struct sfq_slot *slot;
545 struct sk_buff_head list;
18cb8098 546 int dropped = 0;
2ccccf5f 547 unsigned int drop_len = 0;
225d9b89
ED
548
549 __skb_queue_head_init(&list);
550
18cb8098 551 for (i = 0; i < q->maxflows; i++) {
225d9b89
ED
552 slot = &q->slots[i];
553 if (!slot->qlen)
554 continue;
555 while (slot->qlen) {
556 skb = slot_dequeue_head(slot);
557 sfq_dec(q, i);
558 __skb_queue_tail(&list, skb);
559 }
ddecf0f4
ED
560 slot->backlog = 0;
561 red_set_vars(&slot->vars);
225d9b89
ED
562 q->ht[slot->hash] = SFQ_EMPTY_SLOT;
563 }
564 q->tail = NULL;
565
566 while ((skb = __skb_dequeue(&list)) != NULL) {
567 unsigned int hash = sfq_hash(q, skb);
568 sfq_index x = q->ht[hash];
569
570 slot = &q->slots[x];
571 if (x == SFQ_EMPTY_SLOT) {
572 x = q->dep[0].next; /* get a free slot */
18cb8098 573 if (x >= SFQ_MAX_FLOWS) {
25331d6c
JF
574drop:
575 qdisc_qstats_backlog_dec(sch, skb);
2ccccf5f 576 drop_len += qdisc_pkt_len(skb);
18cb8098
ED
577 kfree_skb(skb);
578 dropped++;
579 continue;
580 }
225d9b89
ED
581 q->ht[hash] = x;
582 slot = &q->slots[x];
583 slot->hash = hash;
584 }
18cb8098
ED
585 if (slot->qlen >= q->maxdepth)
586 goto drop;
225d9b89 587 slot_queue_add(slot, skb);
ddecf0f4
ED
588 if (q->red_parms)
589 slot->vars.qavg = red_calc_qavg(q->red_parms,
590 &slot->vars,
591 slot->backlog);
592 slot->backlog += qdisc_pkt_len(skb);
225d9b89
ED
593 sfq_inc(q, x);
594 if (slot->qlen == 1) { /* The flow is new */
595 if (q->tail == NULL) { /* It is the first flow */
596 slot->next = x;
597 } else {
598 slot->next = q->tail->next;
599 q->tail->next = x;
600 }
601 q->tail = slot;
602 slot->allot = q->scaled_quantum;
603 }
604 }
18cb8098 605 sch->q.qlen -= dropped;
2ccccf5f 606 qdisc_tree_reduce_backlog(sch, dropped, drop_len);
225d9b89
ED
607}
608
cdeabbb8 609static void sfq_perturbation(struct timer_list *t)
1da177e4 610{
cdeabbb8
KC
611 struct sfq_sched_data *q = from_timer(q, t, perturb_timer);
612 struct Qdisc *sch = q->sch;
225d9b89 613 spinlock_t *root_lock = qdisc_lock(qdisc_root_sleeping(sch));
1da177e4 614
225d9b89 615 spin_lock(root_lock);
63862b5b 616 q->perturbation = prandom_u32();
225d9b89 617 if (!q->filter_list && q->tail)
18cb8098 618 sfq_rehash(sch);
225d9b89 619 spin_unlock(root_lock);
1da177e4 620
32740ddc
AK
621 if (q->perturb_period)
622 mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
1da177e4
LT
623}
624
1e90474c 625static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
1da177e4
LT
626{
627 struct sfq_sched_data *q = qdisc_priv(sch);
1e90474c 628 struct tc_sfq_qopt *ctl = nla_data(opt);
18cb8098 629 struct tc_sfq_qopt_v1 *ctl_v1 = NULL;
2ccccf5f 630 unsigned int qlen, dropped = 0;
ddecf0f4 631 struct red_parms *p = NULL;
f9ab7425
GF
632 struct sk_buff *to_free = NULL;
633 struct sk_buff *tail = NULL;
1da177e4 634
1e90474c 635 if (opt->nla_len < nla_attr_size(sizeof(*ctl)))
1da177e4 636 return -EINVAL;
18cb8098
ED
637 if (opt->nla_len >= nla_attr_size(sizeof(*ctl_v1)))
638 ctl_v1 = nla_data(opt);
119b3d38 639 if (ctl->divisor &&
640 (!is_power_of_2(ctl->divisor) || ctl->divisor > 65536))
641 return -EINVAL;
ddecf0f4
ED
642 if (ctl_v1 && ctl_v1->qth_min) {
643 p = kmalloc(sizeof(*p), GFP_KERNEL);
644 if (!p)
645 return -ENOMEM;
646 }
1da177e4 647 sch_tree_lock(sch);
18cb8098
ED
648 if (ctl->quantum) {
649 q->quantum = ctl->quantum;
650 q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
651 }
6f9e98f7 652 q->perturb_period = ctl->perturb_period * HZ;
18cb8098
ED
653 if (ctl->flows)
654 q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
655 if (ctl->divisor) {
817fb15d 656 q->divisor = ctl->divisor;
18cb8098
ED
657 q->maxflows = min_t(u32, q->maxflows, q->divisor);
658 }
659 if (ctl_v1) {
660 if (ctl_v1->depth)
661 q->maxdepth = min_t(u32, ctl_v1->depth, SFQ_MAX_DEPTH);
ddecf0f4
ED
662 if (p) {
663 swap(q->red_parms, p);
664 red_set_parms(q->red_parms,
665 ctl_v1->qth_min, ctl_v1->qth_max,
666 ctl_v1->Wlog,
667 ctl_v1->Plog, ctl_v1->Scell_log,
668 NULL,
669 ctl_v1->max_P);
670 }
671 q->flags = ctl_v1->flags;
18cb8098
ED
672 q->headdrop = ctl_v1->headdrop;
673 }
674 if (ctl->limit) {
675 q->limit = min_t(u32, ctl->limit, q->maxdepth * q->maxflows);
676 q->maxflows = min_t(u32, q->maxflows, q->limit);
677 }
678
5e50da01 679 qlen = sch->q.qlen;
f9ab7425
GF
680 while (sch->q.qlen > q->limit) {
681 dropped += sfq_drop(sch, &to_free);
682 if (!tail)
683 tail = to_free;
684 }
685
686 rtnl_kfree_skbs(to_free, tail);
2ccccf5f 687 qdisc_tree_reduce_backlog(sch, qlen - sch->q.qlen, dropped);
1da177e4
LT
688
689 del_timer(&q->perturb_timer);
690 if (q->perturb_period) {
32740ddc 691 mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
63862b5b 692 q->perturbation = prandom_u32();
1da177e4
LT
693 }
694 sch_tree_unlock(sch);
ddecf0f4 695 kfree(p);
1da177e4
LT
696 return 0;
697}
698
bd16a6cc
ED
699static void *sfq_alloc(size_t sz)
700{
752ade68 701 return kvmalloc(sz, GFP_KERNEL);
bd16a6cc
ED
702}
703
704static void sfq_free(void *addr)
705{
4cb28970 706 kvfree(addr);
bd16a6cc
ED
707}
708
709static void sfq_destroy(struct Qdisc *sch)
710{
711 struct sfq_sched_data *q = qdisc_priv(sch);
712
6529eaba 713 tcf_block_put(q->block);
bd16a6cc
ED
714 q->perturb_period = 0;
715 del_timer_sync(&q->perturb_timer);
716 sfq_free(q->ht);
18cb8098 717 sfq_free(q->slots);
ddecf0f4 718 kfree(q->red_parms);
bd16a6cc
ED
719}
720
1e90474c 721static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
1da177e4
LT
722{
723 struct sfq_sched_data *q = qdisc_priv(sch);
724 int i;
6529eaba
JP
725 int err;
726
f85729d0 727 q->sch = sch;
cdeabbb8 728 timer_setup(&q->perturb_timer, sfq_perturbation, TIMER_DEFERRABLE);
e2326576 729
69d78ef2 730 err = tcf_block_get(&q->block, &q->filter_list, sch);
6529eaba
JP
731 if (err)
732 return err;
1da177e4 733
18cb8098
ED
734 for (i = 0; i < SFQ_MAX_DEPTH + 1; i++) {
735 q->dep[i].next = i + SFQ_MAX_FLOWS;
736 q->dep[i].prev = i + SFQ_MAX_FLOWS;
1da177e4 737 }
6f9e98f7 738
18cb8098
ED
739 q->limit = SFQ_MAX_DEPTH;
740 q->maxdepth = SFQ_MAX_DEPTH;
eda83e3b
ED
741 q->cur_depth = 0;
742 q->tail = NULL;
817fb15d 743 q->divisor = SFQ_DEFAULT_HASH_DIVISOR;
18cb8098 744 q->maxflows = SFQ_DEFAULT_FLOWS;
02a9098e
ED
745 q->quantum = psched_mtu(qdisc_dev(sch));
746 q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
747 q->perturb_period = 0;
63862b5b 748 q->perturbation = prandom_u32();
02a9098e
ED
749
750 if (opt) {
1da177e4
LT
751 int err = sfq_change(sch, opt);
752 if (err)
753 return err;
754 }
6f9e98f7 755
bd16a6cc 756 q->ht = sfq_alloc(sizeof(q->ht[0]) * q->divisor);
18cb8098
ED
757 q->slots = sfq_alloc(sizeof(q->slots[0]) * q->maxflows);
758 if (!q->ht || !q->slots) {
87b60cfa 759 /* Note: sfq_destroy() will be called by our caller */
817fb15d 760 return -ENOMEM;
bd16a6cc 761 }
87b60cfa 762
817fb15d
ED
763 for (i = 0; i < q->divisor; i++)
764 q->ht[i] = SFQ_EMPTY_SLOT;
765
18cb8098 766 for (i = 0; i < q->maxflows; i++) {
18c8d82a 767 slot_queue_init(&q->slots[i]);
1da177e4 768 sfq_link(q, i);
18c8d82a 769 }
23624935
ED
770 if (q->limit >= 1)
771 sch->flags |= TCQ_F_CAN_BYPASS;
772 else
773 sch->flags &= ~TCQ_F_CAN_BYPASS;
1da177e4
LT
774 return 0;
775}
776
1da177e4
LT
777static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)
778{
779 struct sfq_sched_data *q = qdisc_priv(sch);
27a884dc 780 unsigned char *b = skb_tail_pointer(skb);
18cb8098 781 struct tc_sfq_qopt_v1 opt;
ddecf0f4 782 struct red_parms *p = q->red_parms;
18cb8098
ED
783
784 memset(&opt, 0, sizeof(opt));
785 opt.v0.quantum = q->quantum;
786 opt.v0.perturb_period = q->perturb_period / HZ;
787 opt.v0.limit = q->limit;
788 opt.v0.divisor = q->divisor;
789 opt.v0.flows = q->maxflows;
790 opt.depth = q->maxdepth;
791 opt.headdrop = q->headdrop;
1da177e4 792
ddecf0f4
ED
793 if (p) {
794 opt.qth_min = p->qth_min >> p->Wlog;
795 opt.qth_max = p->qth_max >> p->Wlog;
796 opt.Wlog = p->Wlog;
797 opt.Plog = p->Plog;
798 opt.Scell_log = p->Scell_log;
799 opt.max_P = p->max_P;
800 }
801 memcpy(&opt.stats, &q->stats, sizeof(opt.stats));
802 opt.flags = q->flags;
803
1b34ec43
DM
804 if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
805 goto nla_put_failure;
1da177e4
LT
806
807 return skb->len;
808
1e90474c 809nla_put_failure:
dc5fc579 810 nlmsg_trim(skb, b);
1da177e4
LT
811 return -1;
812}
813
41065fba
JP
814static struct Qdisc *sfq_leaf(struct Qdisc *sch, unsigned long arg)
815{
816 return NULL;
817}
818
143976ce 819static unsigned long sfq_find(struct Qdisc *sch, u32 classid)
7d2681a6
PM
820{
821 return 0;
822}
823
eb4a5527
JP
824static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent,
825 u32 classid)
826{
23624935
ED
827 /* we cannot bypass queue discipline anymore */
828 sch->flags &= ~TCQ_F_CAN_BYPASS;
eb4a5527
JP
829 return 0;
830}
831
143976ce 832static void sfq_unbind(struct Qdisc *q, unsigned long cl)
da7115d9
JP
833{
834}
835
6529eaba 836static struct tcf_block *sfq_tcf_block(struct Qdisc *sch, unsigned long cl)
7d2681a6
PM
837{
838 struct sfq_sched_data *q = qdisc_priv(sch);
839
840 if (cl)
841 return NULL;
6529eaba 842 return q->block;
7d2681a6
PM
843}
844
94de78d1
PM
845static int sfq_dump_class(struct Qdisc *sch, unsigned long cl,
846 struct sk_buff *skb, struct tcmsg *tcm)
847{
848 tcm->tcm_handle |= TC_H_MIN(cl);
849 return 0;
850}
851
852static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
853 struct gnet_dump *d)
854{
855 struct sfq_sched_data *q = qdisc_priv(sch);
ee09b3c1
ED
856 sfq_index idx = q->ht[cl - 1];
857 struct gnet_stats_queue qs = { 0 };
858 struct tc_sfq_xstats xstats = { 0 };
c4266263 859
ee09b3c1
ED
860 if (idx != SFQ_EMPTY_SLOT) {
861 const struct sfq_slot *slot = &q->slots[idx];
94de78d1 862
eeaeb068 863 xstats.allot = slot->allot << SFQ_ALLOT_SHIFT;
ee09b3c1 864 qs.qlen = slot->qlen;
ddecf0f4 865 qs.backlog = slot->backlog;
ee09b3c1 866 }
b0ab6f92 867 if (gnet_stats_copy_queue(d, NULL, &qs, qs.qlen) < 0)
94de78d1
PM
868 return -1;
869 return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
870}
871
7d2681a6
PM
872static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
873{
94de78d1
PM
874 struct sfq_sched_data *q = qdisc_priv(sch);
875 unsigned int i;
876
877 if (arg->stop)
878 return;
879
817fb15d 880 for (i = 0; i < q->divisor; i++) {
eda83e3b 881 if (q->ht[i] == SFQ_EMPTY_SLOT ||
94de78d1
PM
882 arg->count < arg->skip) {
883 arg->count++;
884 continue;
885 }
886 if (arg->fn(sch, i + 1, arg) < 0) {
887 arg->stop = 1;
888 break;
889 }
890 arg->count++;
891 }
7d2681a6
PM
892}
893
894static const struct Qdisc_class_ops sfq_class_ops = {
41065fba 895 .leaf = sfq_leaf,
143976ce 896 .find = sfq_find,
6529eaba 897 .tcf_block = sfq_tcf_block,
eb4a5527 898 .bind_tcf = sfq_bind,
143976ce 899 .unbind_tcf = sfq_unbind,
94de78d1
PM
900 .dump = sfq_dump_class,
901 .dump_stats = sfq_dump_class_stats,
7d2681a6
PM
902 .walk = sfq_walk,
903};
904
20fea08b 905static struct Qdisc_ops sfq_qdisc_ops __read_mostly = {
7d2681a6 906 .cl_ops = &sfq_class_ops,
1da177e4
LT
907 .id = "sfq",
908 .priv_size = sizeof(struct sfq_sched_data),
909 .enqueue = sfq_enqueue,
910 .dequeue = sfq_dequeue,
07bd8df5 911 .peek = qdisc_peek_dequeued,
1da177e4
LT
912 .init = sfq_init,
913 .reset = sfq_reset,
914 .destroy = sfq_destroy,
915 .change = NULL,
916 .dump = sfq_dump,
917 .owner = THIS_MODULE,
918};
919
920static int __init sfq_module_init(void)
921{
922 return register_qdisc(&sfq_qdisc_ops);
923}
10297b99 924static void __exit sfq_module_exit(void)
1da177e4
LT
925{
926 unregister_qdisc(&sfq_qdisc_ops);
927}
928module_init(sfq_module_init)
929module_exit(sfq_module_exit)
930MODULE_LICENSE("GPL");