]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - net/sched/sch_sfq.c
cls_flower: Fix incorrect idr release when failing to modify rule
[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;
8afa10cb
NF
642 if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max,
643 ctl_v1->Wlog))
644 return -EINVAL;
ddecf0f4
ED
645 if (ctl_v1 && ctl_v1->qth_min) {
646 p = kmalloc(sizeof(*p), GFP_KERNEL);
647 if (!p)
648 return -ENOMEM;
649 }
1da177e4 650 sch_tree_lock(sch);
18cb8098
ED
651 if (ctl->quantum) {
652 q->quantum = ctl->quantum;
653 q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
654 }
6f9e98f7 655 q->perturb_period = ctl->perturb_period * HZ;
18cb8098
ED
656 if (ctl->flows)
657 q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
658 if (ctl->divisor) {
817fb15d 659 q->divisor = ctl->divisor;
18cb8098
ED
660 q->maxflows = min_t(u32, q->maxflows, q->divisor);
661 }
662 if (ctl_v1) {
663 if (ctl_v1->depth)
664 q->maxdepth = min_t(u32, ctl_v1->depth, SFQ_MAX_DEPTH);
ddecf0f4
ED
665 if (p) {
666 swap(q->red_parms, p);
667 red_set_parms(q->red_parms,
668 ctl_v1->qth_min, ctl_v1->qth_max,
669 ctl_v1->Wlog,
670 ctl_v1->Plog, ctl_v1->Scell_log,
671 NULL,
672 ctl_v1->max_P);
673 }
674 q->flags = ctl_v1->flags;
18cb8098
ED
675 q->headdrop = ctl_v1->headdrop;
676 }
677 if (ctl->limit) {
678 q->limit = min_t(u32, ctl->limit, q->maxdepth * q->maxflows);
679 q->maxflows = min_t(u32, q->maxflows, q->limit);
680 }
681
5e50da01 682 qlen = sch->q.qlen;
f9ab7425
GF
683 while (sch->q.qlen > q->limit) {
684 dropped += sfq_drop(sch, &to_free);
685 if (!tail)
686 tail = to_free;
687 }
688
689 rtnl_kfree_skbs(to_free, tail);
2ccccf5f 690 qdisc_tree_reduce_backlog(sch, qlen - sch->q.qlen, dropped);
1da177e4
LT
691
692 del_timer(&q->perturb_timer);
693 if (q->perturb_period) {
32740ddc 694 mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
63862b5b 695 q->perturbation = prandom_u32();
1da177e4
LT
696 }
697 sch_tree_unlock(sch);
ddecf0f4 698 kfree(p);
1da177e4
LT
699 return 0;
700}
701
bd16a6cc
ED
702static void *sfq_alloc(size_t sz)
703{
752ade68 704 return kvmalloc(sz, GFP_KERNEL);
bd16a6cc
ED
705}
706
707static void sfq_free(void *addr)
708{
4cb28970 709 kvfree(addr);
bd16a6cc
ED
710}
711
712static void sfq_destroy(struct Qdisc *sch)
713{
714 struct sfq_sched_data *q = qdisc_priv(sch);
715
6529eaba 716 tcf_block_put(q->block);
bd16a6cc
ED
717 q->perturb_period = 0;
718 del_timer_sync(&q->perturb_timer);
719 sfq_free(q->ht);
18cb8098 720 sfq_free(q->slots);
ddecf0f4 721 kfree(q->red_parms);
bd16a6cc
ED
722}
723
1e90474c 724static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
1da177e4
LT
725{
726 struct sfq_sched_data *q = qdisc_priv(sch);
727 int i;
6529eaba
JP
728 int err;
729
f85729d0 730 q->sch = sch;
cdeabbb8 731 timer_setup(&q->perturb_timer, sfq_perturbation, TIMER_DEFERRABLE);
e2326576 732
69d78ef2 733 err = tcf_block_get(&q->block, &q->filter_list, sch);
6529eaba
JP
734 if (err)
735 return err;
1da177e4 736
18cb8098
ED
737 for (i = 0; i < SFQ_MAX_DEPTH + 1; i++) {
738 q->dep[i].next = i + SFQ_MAX_FLOWS;
739 q->dep[i].prev = i + SFQ_MAX_FLOWS;
1da177e4 740 }
6f9e98f7 741
18cb8098
ED
742 q->limit = SFQ_MAX_DEPTH;
743 q->maxdepth = SFQ_MAX_DEPTH;
eda83e3b
ED
744 q->cur_depth = 0;
745 q->tail = NULL;
817fb15d 746 q->divisor = SFQ_DEFAULT_HASH_DIVISOR;
18cb8098 747 q->maxflows = SFQ_DEFAULT_FLOWS;
02a9098e
ED
748 q->quantum = psched_mtu(qdisc_dev(sch));
749 q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
750 q->perturb_period = 0;
63862b5b 751 q->perturbation = prandom_u32();
02a9098e
ED
752
753 if (opt) {
1da177e4
LT
754 int err = sfq_change(sch, opt);
755 if (err)
756 return err;
757 }
6f9e98f7 758
bd16a6cc 759 q->ht = sfq_alloc(sizeof(q->ht[0]) * q->divisor);
18cb8098
ED
760 q->slots = sfq_alloc(sizeof(q->slots[0]) * q->maxflows);
761 if (!q->ht || !q->slots) {
87b60cfa 762 /* Note: sfq_destroy() will be called by our caller */
817fb15d 763 return -ENOMEM;
bd16a6cc 764 }
87b60cfa 765
817fb15d
ED
766 for (i = 0; i < q->divisor; i++)
767 q->ht[i] = SFQ_EMPTY_SLOT;
768
18cb8098 769 for (i = 0; i < q->maxflows; i++) {
18c8d82a 770 slot_queue_init(&q->slots[i]);
1da177e4 771 sfq_link(q, i);
18c8d82a 772 }
23624935
ED
773 if (q->limit >= 1)
774 sch->flags |= TCQ_F_CAN_BYPASS;
775 else
776 sch->flags &= ~TCQ_F_CAN_BYPASS;
1da177e4
LT
777 return 0;
778}
779
1da177e4
LT
780static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)
781{
782 struct sfq_sched_data *q = qdisc_priv(sch);
27a884dc 783 unsigned char *b = skb_tail_pointer(skb);
18cb8098 784 struct tc_sfq_qopt_v1 opt;
ddecf0f4 785 struct red_parms *p = q->red_parms;
18cb8098
ED
786
787 memset(&opt, 0, sizeof(opt));
788 opt.v0.quantum = q->quantum;
789 opt.v0.perturb_period = q->perturb_period / HZ;
790 opt.v0.limit = q->limit;
791 opt.v0.divisor = q->divisor;
792 opt.v0.flows = q->maxflows;
793 opt.depth = q->maxdepth;
794 opt.headdrop = q->headdrop;
1da177e4 795
ddecf0f4
ED
796 if (p) {
797 opt.qth_min = p->qth_min >> p->Wlog;
798 opt.qth_max = p->qth_max >> p->Wlog;
799 opt.Wlog = p->Wlog;
800 opt.Plog = p->Plog;
801 opt.Scell_log = p->Scell_log;
802 opt.max_P = p->max_P;
803 }
804 memcpy(&opt.stats, &q->stats, sizeof(opt.stats));
805 opt.flags = q->flags;
806
1b34ec43
DM
807 if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
808 goto nla_put_failure;
1da177e4
LT
809
810 return skb->len;
811
1e90474c 812nla_put_failure:
dc5fc579 813 nlmsg_trim(skb, b);
1da177e4
LT
814 return -1;
815}
816
41065fba
JP
817static struct Qdisc *sfq_leaf(struct Qdisc *sch, unsigned long arg)
818{
819 return NULL;
820}
821
143976ce 822static unsigned long sfq_find(struct Qdisc *sch, u32 classid)
7d2681a6
PM
823{
824 return 0;
825}
826
eb4a5527
JP
827static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent,
828 u32 classid)
829{
23624935
ED
830 /* we cannot bypass queue discipline anymore */
831 sch->flags &= ~TCQ_F_CAN_BYPASS;
eb4a5527
JP
832 return 0;
833}
834
143976ce 835static void sfq_unbind(struct Qdisc *q, unsigned long cl)
da7115d9
JP
836{
837}
838
6529eaba 839static struct tcf_block *sfq_tcf_block(struct Qdisc *sch, unsigned long cl)
7d2681a6
PM
840{
841 struct sfq_sched_data *q = qdisc_priv(sch);
842
843 if (cl)
844 return NULL;
6529eaba 845 return q->block;
7d2681a6
PM
846}
847
94de78d1
PM
848static int sfq_dump_class(struct Qdisc *sch, unsigned long cl,
849 struct sk_buff *skb, struct tcmsg *tcm)
850{
851 tcm->tcm_handle |= TC_H_MIN(cl);
852 return 0;
853}
854
855static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
856 struct gnet_dump *d)
857{
858 struct sfq_sched_data *q = qdisc_priv(sch);
ee09b3c1
ED
859 sfq_index idx = q->ht[cl - 1];
860 struct gnet_stats_queue qs = { 0 };
861 struct tc_sfq_xstats xstats = { 0 };
c4266263 862
ee09b3c1
ED
863 if (idx != SFQ_EMPTY_SLOT) {
864 const struct sfq_slot *slot = &q->slots[idx];
94de78d1 865
eeaeb068 866 xstats.allot = slot->allot << SFQ_ALLOT_SHIFT;
ee09b3c1 867 qs.qlen = slot->qlen;
ddecf0f4 868 qs.backlog = slot->backlog;
ee09b3c1 869 }
b0ab6f92 870 if (gnet_stats_copy_queue(d, NULL, &qs, qs.qlen) < 0)
94de78d1
PM
871 return -1;
872 return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
873}
874
7d2681a6
PM
875static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
876{
94de78d1
PM
877 struct sfq_sched_data *q = qdisc_priv(sch);
878 unsigned int i;
879
880 if (arg->stop)
881 return;
882
817fb15d 883 for (i = 0; i < q->divisor; i++) {
eda83e3b 884 if (q->ht[i] == SFQ_EMPTY_SLOT ||
94de78d1
PM
885 arg->count < arg->skip) {
886 arg->count++;
887 continue;
888 }
889 if (arg->fn(sch, i + 1, arg) < 0) {
890 arg->stop = 1;
891 break;
892 }
893 arg->count++;
894 }
7d2681a6
PM
895}
896
897static const struct Qdisc_class_ops sfq_class_ops = {
41065fba 898 .leaf = sfq_leaf,
143976ce 899 .find = sfq_find,
6529eaba 900 .tcf_block = sfq_tcf_block,
eb4a5527 901 .bind_tcf = sfq_bind,
143976ce 902 .unbind_tcf = sfq_unbind,
94de78d1
PM
903 .dump = sfq_dump_class,
904 .dump_stats = sfq_dump_class_stats,
7d2681a6
PM
905 .walk = sfq_walk,
906};
907
20fea08b 908static struct Qdisc_ops sfq_qdisc_ops __read_mostly = {
7d2681a6 909 .cl_ops = &sfq_class_ops,
1da177e4
LT
910 .id = "sfq",
911 .priv_size = sizeof(struct sfq_sched_data),
912 .enqueue = sfq_enqueue,
913 .dequeue = sfq_dequeue,
07bd8df5 914 .peek = qdisc_peek_dequeued,
1da177e4
LT
915 .init = sfq_init,
916 .reset = sfq_reset,
917 .destroy = sfq_destroy,
918 .change = NULL,
919 .dump = sfq_dump,
920 .owner = THIS_MODULE,
921};
922
923static int __init sfq_module_init(void)
924{
925 return register_qdisc(&sfq_qdisc_ops);
926}
10297b99 927static void __exit sfq_module_exit(void)
1da177e4
LT
928{
929 unregister_qdisc(&sfq_qdisc_ops);
930}
931module_init(sfq_module_init)
932module_exit(sfq_module_exit)
933MODULE_LICENSE("GPL");