sch_sfq.c 22.5 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * net/sched/sch_sfq.c	Stochastic Fairness Queueing discipline.
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 *
 * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
#include <linux/string.h>
#include <linux/in.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/skbuff.h>
21
#include <linux/siphash.h>
22
#include <linux/slab.h>
23
#include <linux/vmalloc.h>
24
#include <net/netlink.h>
L
Linus Torvalds 已提交
25
#include <net/pkt_sched.h>
26
#include <net/pkt_cls.h>
27
#include <net/red.h>
L
Linus Torvalds 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45


/*	Stochastic Fairness Queuing algorithm.
	=======================================

	Source:
	Paul E. McKenney "Stochastic Fairness Queuing",
	IEEE INFOCOMM'90 Proceedings, San Francisco, 1990.

	Paul E. McKenney "Stochastic Fairness Queuing",
	"Interworking: Research and Experience", v.2, 1991, p.113-131.


	See also:
	M. Shreedhar and George Varghese "Efficient Fair
	Queuing using Deficit Round Robin", Proc. SIGCOMM 95.


46
	This is not the thing that is usually called (W)FQ nowadays.
L
Linus Torvalds 已提交
47 48 49 50 51 52 53 54 55
	It does not use any timestamp mechanism, but instead
	processes queues in round-robin order.

	ADVANTAGE:

	- It is very cheap. Both CPU and memory requirements are minimal.

	DRAWBACKS:

56
	- "Stochastic" -> It is not 100% fair.
L
Linus Torvalds 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69
	When hash collisions occur, several flows are considered as one.

	- "Round-robin" -> It introduces larger delays than virtual clock
	based schemes, and should not be used for isolating interactive
	traffic	from non-interactive. It means, that this scheduler
	should be used as leaf of CBQ or P3, which put interactive traffic
	to higher priority band.

	We still need true WFQ for top level CSZ, but using WFQ
	for the best effort traffic is absolutely pointless:
	SFQ is superior for this purpose.

	IMPLEMENTATION:
E
Eric Dumazet 已提交
70 71 72 73 74
	This implementation limits :
	- maximal queue length per flow to 127 packets.
	- max mtu to 2^18-1;
	- max 65408 flows,
	- number of hash buckets to 65536.
L
Linus Torvalds 已提交
75 76 77

	It is easy to increase these values, but not in flight.  */

E
Eric Dumazet 已提交
78 79 80 81
#define SFQ_MAX_DEPTH		127 /* max number of packets per flow */
#define SFQ_DEFAULT_FLOWS	128
#define SFQ_MAX_FLOWS		(0x10000 - SFQ_MAX_DEPTH - 1) /* max number of flows */
#define SFQ_EMPTY_SLOT		0xffff
82 83
#define SFQ_DEFAULT_HASH_DIVISOR 1024

84 85 86 87 88
/* We use 16 bits to store allot, and want to handle packets up to 64K
 * Scale allot by 8 (1<<3) so that no overflow occurs.
 */
#define SFQ_ALLOT_SHIFT		3
#define SFQ_ALLOT_SIZE(X)	DIV_ROUND_UP(X, 1 << SFQ_ALLOT_SHIFT)
L
Linus Torvalds 已提交
89

E
Eric Dumazet 已提交
90 91
/* This type should contain at least SFQ_MAX_DEPTH + 1 + SFQ_MAX_FLOWS values */
typedef u16 sfq_index;
L
Linus Torvalds 已提交
92

93 94
/*
 * We dont use pointers to save space.
E
Eric Dumazet 已提交
95 96
 * Small indexes [0 ... SFQ_MAX_FLOWS - 1] are 'pointers' to slots[] array
 * while following values [SFQ_MAX_FLOWS ... SFQ_MAX_FLOWS + SFQ_MAX_DEPTH]
97 98
 * are 'pointers' to dep[] array
 */
E
Eric Dumazet 已提交
99
struct sfq_head {
L
Linus Torvalds 已提交
100 101 102 103
	sfq_index	next;
	sfq_index	prev;
};

104 105 106 107
struct sfq_slot {
	struct sk_buff	*skblist_next;
	struct sk_buff	*skblist_prev;
	sfq_index	qlen; /* number of skbs in skblist */
E
Eric Dumazet 已提交
108
	sfq_index	next; /* next slot in sfq RR chain */
109 110 111
	struct sfq_head dep; /* anchor in dep[] chains */
	unsigned short	hash; /* hash value (index in ht[]) */
	short		allot; /* credit for this slot */
112 113 114

	unsigned int    backlog;
	struct red_vars vars;
115 116
};

E
Eric Dumazet 已提交
117
struct sfq_sched_data {
E
Eric Dumazet 已提交
118 119
/* frequently used fields */
	int		limit;		/* limit of total number of packets in this qdisc */
120
	unsigned int	divisor;	/* number of slots in hash table */
121 122
	u8		headdrop;
	u8		maxdepth;	/* limit of packets per flow */
E
Eric Dumazet 已提交
123

124
	siphash_key_t 	perturbation;
125 126
	u8		cur_depth;	/* depth of longest slot */
	u8		flags;
127
	unsigned short  scaled_quantum; /* SFQ_ALLOT_SIZE(quantum) */
J
John Fastabend 已提交
128
	struct tcf_proto __rcu *filter_list;
129
	struct tcf_block *block;
E
Eric Dumazet 已提交
130 131 132
	sfq_index	*ht;		/* Hash table ('divisor' slots) */
	struct sfq_slot	*slots;		/* Flows table ('maxflows' entries) */

133 134 135 136
	struct red_parms *red_parms;
	struct tc_sfqred_stats stats;
	struct sfq_slot *tail;		/* current slot in round */

E
Eric Dumazet 已提交
137 138 139 140 141 142 143
	struct sfq_head	dep[SFQ_MAX_DEPTH + 1];
					/* Linked lists of slots, indexed by depth
					 * dep[0] : list of unused flows
					 * dep[1] : list of flows with 1 packet
					 * dep[X] : list of flows with X packets
					 */

144
	unsigned int	maxflows;	/* number of flows in flows array */
E
Eric Dumazet 已提交
145 146 147
	int		perturb_period;
	unsigned int	quantum;	/* Allotment per round: MUST BE >= MTU */
	struct timer_list perturb_timer;
148
	struct Qdisc	*sch;
L
Linus Torvalds 已提交
149 150
};

151 152 153 154 155
/*
 * sfq_head are either in a sfq_slot or in dep[] array
 */
static inline struct sfq_head *sfq_dep_head(struct sfq_sched_data *q, sfq_index val)
{
E
Eric Dumazet 已提交
156
	if (val < SFQ_MAX_FLOWS)
157
		return &q->slots[val].dep;
E
Eric Dumazet 已提交
158
	return &q->dep[val - SFQ_MAX_FLOWS];
159 160
}

E
Eric Dumazet 已提交
161 162
static unsigned int sfq_hash(const struct sfq_sched_data *q,
			     const struct sk_buff *skb)
L
Linus Torvalds 已提交
163
{
164
	return skb_get_hash_perturb(skb, &q->perturbation) & (q->divisor - 1);
L
Linus Torvalds 已提交
165 166
}

167 168 169 170 171
static unsigned int sfq_classify(struct sk_buff *skb, struct Qdisc *sch,
				 int *qerr)
{
	struct sfq_sched_data *q = qdisc_priv(sch);
	struct tcf_result res;
J
John Fastabend 已提交
172
	struct tcf_proto *fl;
173 174 175 176
	int result;

	if (TC_H_MAJ(skb->priority) == sch->handle &&
	    TC_H_MIN(skb->priority) > 0 &&
177
	    TC_H_MIN(skb->priority) <= q->divisor)
178 179
		return TC_H_MIN(skb->priority);

J
John Fastabend 已提交
180
	fl = rcu_dereference_bh(q->filter_list);
181
	if (!fl)
182 183
		return sfq_hash(q, skb) + 1;

184
	*qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
185
	result = tcf_classify(skb, fl, &res, false);
186 187 188 189 190
	if (result >= 0) {
#ifdef CONFIG_NET_CLS_ACT
		switch (result) {
		case TC_ACT_STOLEN:
		case TC_ACT_QUEUED:
191
		case TC_ACT_TRAP:
192
			*qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
193
			/* fall through */
194 195 196 197
		case TC_ACT_SHOT:
			return 0;
		}
#endif
198
		if (TC_H_MIN(res.classid) <= q->divisor)
199 200 201 202 203
			return TC_H_MIN(res.classid);
	}
	return 0;
}

204
/*
E
Eric Dumazet 已提交
205
 * x : slot number [0 .. SFQ_MAX_FLOWS - 1]
206
 */
L
Linus Torvalds 已提交
207 208 209
static inline void sfq_link(struct sfq_sched_data *q, sfq_index x)
{
	sfq_index p, n;
E
Eric Dumazet 已提交
210 211
	struct sfq_slot *slot = &q->slots[x];
	int qlen = slot->qlen;
212

E
Eric Dumazet 已提交
213
	p = qlen + SFQ_MAX_FLOWS;
214
	n = q->dep[qlen].next;
L
Linus Torvalds 已提交
215

E
Eric Dumazet 已提交
216 217
	slot->dep.next = n;
	slot->dep.prev = p;
218 219 220

	q->dep[qlen].next = x;		/* sfq_dep_head(q, p)->next = x */
	sfq_dep_head(q, n)->prev = x;
L
Linus Torvalds 已提交
221 222
}

223
#define sfq_unlink(q, x, n, p)			\
224 225 226 227 228 229
	do {					\
		n = q->slots[x].dep.next;	\
		p = q->slots[x].dep.prev;	\
		sfq_dep_head(q, p)->next = n;	\
		sfq_dep_head(q, n)->prev = p;	\
	} while (0)
230 231


L
Linus Torvalds 已提交
232 233 234
static inline void sfq_dec(struct sfq_sched_data *q, sfq_index x)
{
	sfq_index p, n;
235
	int d;
L
Linus Torvalds 已提交
236

237
	sfq_unlink(q, x, n, p);
L
Linus Torvalds 已提交
238

239 240 241
	d = q->slots[x].qlen--;
	if (n == p && q->cur_depth == d)
		q->cur_depth--;
L
Linus Torvalds 已提交
242 243 244 245 246 247 248 249
	sfq_link(q, x);
}

static inline void sfq_inc(struct sfq_sched_data *q, sfq_index x)
{
	sfq_index p, n;
	int d;

250
	sfq_unlink(q, x, n, p);
L
Linus Torvalds 已提交
251

252 253 254
	d = ++q->slots[x].qlen;
	if (q->cur_depth < d)
		q->cur_depth = d;
L
Linus Torvalds 已提交
255 256 257
	sfq_link(q, x);
}

258 259 260 261 262 263 264 265
/* helper functions : might be changed when/if skb use a standard list_head */

/* remove one skb from tail of slot queue */
static inline struct sk_buff *slot_dequeue_tail(struct sfq_slot *slot)
{
	struct sk_buff *skb = slot->skblist_prev;

	slot->skblist_prev = skb->prev;
E
Eric Dumazet 已提交
266
	skb->prev->next = (struct sk_buff *)slot;
267 268 269 270 271 272 273 274 275 276
	skb->next = skb->prev = NULL;
	return skb;
}

/* remove one skb from head of slot queue */
static inline struct sk_buff *slot_dequeue_head(struct sfq_slot *slot)
{
	struct sk_buff *skb = slot->skblist_next;

	slot->skblist_next = skb->next;
E
Eric Dumazet 已提交
277
	skb->next->prev = (struct sk_buff *)slot;
278 279 280 281 282 283
	skb->next = skb->prev = NULL;
	return skb;
}

static inline void slot_queue_init(struct sfq_slot *slot)
{
E
Eric Dumazet 已提交
284
	memset(slot, 0, sizeof(*slot));
285 286 287 288 289 290 291 292 293 294 295 296
	slot->skblist_prev = slot->skblist_next = (struct sk_buff *)slot;
}

/* add skb to slot queue (tail add) */
static inline void slot_queue_add(struct sfq_slot *slot, struct sk_buff *skb)
{
	skb->prev = slot->skblist_prev;
	skb->next = (struct sk_buff *)slot;
	slot->skblist_prev->next = skb;
	slot->skblist_prev = skb;
}

297
static unsigned int sfq_drop(struct Qdisc *sch, struct sk_buff **to_free)
L
Linus Torvalds 已提交
298 299
{
	struct sfq_sched_data *q = qdisc_priv(sch);
300
	sfq_index x, d = q->cur_depth;
L
Linus Torvalds 已提交
301 302
	struct sk_buff *skb;
	unsigned int len;
303
	struct sfq_slot *slot;
L
Linus Torvalds 已提交
304

305
	/* Queue is full! Find the longest slot and drop tail packet from it */
L
Linus Torvalds 已提交
306
	if (d > 1) {
307 308 309
		x = q->dep[d].next;
		slot = &q->slots[x];
drop:
E
Eric Dumazet 已提交
310
		skb = q->headdrop ? slot_dequeue_head(slot) : slot_dequeue_tail(slot);
311
		len = qdisc_pkt_len(skb);
312
		slot->backlog -= len;
L
Linus Torvalds 已提交
313 314
		sfq_dec(q, x);
		sch->q.qlen--;
315
		qdisc_qstats_backlog_dec(sch, skb);
316
		qdisc_drop(skb, sch, to_free);
L
Linus Torvalds 已提交
317 318 319 320 321
		return len;
	}

	if (d == 1) {
		/* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
322 323 324 325 326
		x = q->tail->next;
		slot = &q->slots[x];
		q->tail->next = slot->next;
		q->ht[slot->hash] = SFQ_EMPTY_SLOT;
		goto drop;
L
Linus Torvalds 已提交
327 328 329 330 331
	}

	return 0;
}

332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348
/* Is ECN parameter configured */
static int sfq_prob_mark(const struct sfq_sched_data *q)
{
	return q->flags & TC_RED_ECN;
}

/* Should packets over max threshold just be marked */
static int sfq_hard_mark(const struct sfq_sched_data *q)
{
	return (q->flags & (TC_RED_ECN | TC_RED_HARDDROP)) == TC_RED_ECN;
}

static int sfq_headdrop(const struct sfq_sched_data *q)
{
	return q->headdrop;
}

L
Linus Torvalds 已提交
349
static int
350
sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)
L
Linus Torvalds 已提交
351 352
{
	struct sfq_sched_data *q = qdisc_priv(sch);
353
	unsigned int hash, dropped;
354
	sfq_index x, qlen;
355
	struct sfq_slot *slot;
356
	int uninitialized_var(ret);
357 358
	struct sk_buff *head;
	int delta;
359 360 361

	hash = sfq_classify(skb, sch, &ret);
	if (hash == 0) {
362
		if (ret & __NET_XMIT_BYPASS)
363
			qdisc_qstats_drop(sch);
364
		__qdisc_drop(skb, to_free);
365 366 367
		return ret;
	}
	hash--;
L
Linus Torvalds 已提交
368 369

	x = q->ht[hash];
370 371 372
	slot = &q->slots[x];
	if (x == SFQ_EMPTY_SLOT) {
		x = q->dep[0].next; /* get a free slot */
E
Eric Dumazet 已提交
373
		if (x >= SFQ_MAX_FLOWS)
374
			return qdisc_drop(skb, sch, to_free);
375 376 377
		q->ht[hash] = x;
		slot = &q->slots[x];
		slot->hash = hash;
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392
		slot->backlog = 0; /* should already be 0 anyway... */
		red_set_vars(&slot->vars);
		goto enqueue;
	}
	if (q->red_parms) {
		slot->vars.qavg = red_calc_qavg_no_idle_time(q->red_parms,
							&slot->vars,
							slot->backlog);
		switch (red_action(q->red_parms,
				   &slot->vars,
				   slot->vars.qavg)) {
		case RED_DONT_MARK:
			break;

		case RED_PROB_MARK:
393
			qdisc_qstats_overlimit(sch);
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
			if (sfq_prob_mark(q)) {
				/* We know we have at least one packet in queue */
				if (sfq_headdrop(q) &&
				    INET_ECN_set_ce(slot->skblist_next)) {
					q->stats.prob_mark_head++;
					break;
				}
				if (INET_ECN_set_ce(skb)) {
					q->stats.prob_mark++;
					break;
				}
			}
			q->stats.prob_drop++;
			goto congestion_drop;

		case RED_HARD_MARK:
410
			qdisc_qstats_overlimit(sch);
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
			if (sfq_hard_mark(q)) {
				/* We know we have at least one packet in queue */
				if (sfq_headdrop(q) &&
				    INET_ECN_set_ce(slot->skblist_next)) {
					q->stats.forced_mark_head++;
					break;
				}
				if (INET_ECN_set_ce(skb)) {
					q->stats.forced_mark++;
					break;
				}
			}
			q->stats.forced_drop++;
			goto congestion_drop;
		}
L
Linus Torvalds 已提交
426
	}
427

E
Eric Dumazet 已提交
428
	if (slot->qlen >= q->maxdepth) {
429 430
congestion_drop:
		if (!sfq_headdrop(q))
431
			return qdisc_drop(skb, sch, to_free);
E
Eric Dumazet 已提交
432

433
		/* We know we have at least one packet in queue */
E
Eric Dumazet 已提交
434
		head = slot_dequeue_head(slot);
435 436 437
		delta = qdisc_pkt_len(head) - qdisc_pkt_len(skb);
		sch->qstats.backlog -= delta;
		slot->backlog -= delta;
438
		qdisc_drop(head, sch, to_free);
E
Eric Dumazet 已提交
439 440

		slot_queue_add(slot, skb);
441
		qdisc_tree_reduce_backlog(sch, 0, delta);
E
Eric Dumazet 已提交
442 443
		return NET_XMIT_CN;
	}
444

445
enqueue:
446
	qdisc_qstats_backlog_inc(sch, skb);
447
	slot->backlog += qdisc_pkt_len(skb);
448
	slot_queue_add(slot, skb);
L
Linus Torvalds 已提交
449
	sfq_inc(q, x);
450 451 452
	if (slot->qlen == 1) {		/* The flow is new */
		if (q->tail == NULL) {	/* It is the first flow */
			slot->next = x;
L
Linus Torvalds 已提交
453
		} else {
454 455
			slot->next = q->tail->next;
			q->tail->next = x;
L
Linus Torvalds 已提交
456
		}
457 458 459 460 461
		/* We put this flow at the end of our flow list.
		 * This might sound unfair for a new flow to wait after old ones,
		 * but we could endup servicing new flows only, and freeze old ones.
		 */
		q->tail = slot;
462
		/* We could use a bigger initial quantum for new flows */
463
		slot->allot = q->scaled_quantum;
L
Linus Torvalds 已提交
464
	}
465
	if (++sch->q.qlen <= q->limit)
466
		return NET_XMIT_SUCCESS;
L
Linus Torvalds 已提交
467

468
	qlen = slot->qlen;
469
	dropped = sfq_drop(sch, to_free);
470 471 472
	/* Return Congestion Notification only if we dropped a packet
	 * from this flow.
	 */
473 474
	if (qlen != slot->qlen) {
		qdisc_tree_reduce_backlog(sch, 0, dropped - qdisc_pkt_len(skb));
E
Eric Dumazet 已提交
475
		return NET_XMIT_CN;
476
	}
E
Eric Dumazet 已提交
477 478

	/* As we dropped a packet, better let upper stack know this */
479
	qdisc_tree_reduce_backlog(sch, 1, dropped);
E
Eric Dumazet 已提交
480
	return NET_XMIT_SUCCESS;
L
Linus Torvalds 已提交
481 482 483
}

static struct sk_buff *
484
sfq_dequeue(struct Qdisc *sch)
L
Linus Torvalds 已提交
485 486 487
{
	struct sfq_sched_data *q = qdisc_priv(sch);
	struct sk_buff *skb;
488
	sfq_index a, next_a;
489
	struct sfq_slot *slot;
L
Linus Torvalds 已提交
490 491

	/* No active slots */
492
	if (q->tail == NULL)
L
Linus Torvalds 已提交
493 494
		return NULL;

495
next_slot:
496 497
	a = q->tail->next;
	slot = &q->slots[a];
498 499 500 501 502
	if (slot->allot <= 0) {
		q->tail = slot;
		slot->allot += q->scaled_quantum;
		goto next_slot;
	}
503
	skb = slot_dequeue_head(slot);
L
Linus Torvalds 已提交
504
	sfq_dec(q, a);
505
	qdisc_bstats_update(sch, skb);
L
Linus Torvalds 已提交
506
	sch->q.qlen--;
507
	qdisc_qstats_backlog_dec(sch, skb);
508
	slot->backlog -= qdisc_pkt_len(skb);
L
Linus Torvalds 已提交
509
	/* Is the slot empty? */
510 511 512
	if (slot->qlen == 0) {
		q->ht[slot->hash] = SFQ_EMPTY_SLOT;
		next_a = slot->next;
513
		if (a == next_a) {
514
			q->tail = NULL; /* no more active slots */
L
Linus Torvalds 已提交
515 516
			return skb;
		}
517
		q->tail->next = next_a;
518 519
	} else {
		slot->allot -= SFQ_ALLOT_SIZE(qdisc_pkt_len(skb));
L
Linus Torvalds 已提交
520 521 522 523 524
	}
	return skb;
}

static void
525
sfq_reset(struct Qdisc *sch)
L
Linus Torvalds 已提交
526 527 528 529
{
	struct sk_buff *skb;

	while ((skb = sfq_dequeue(sch)) != NULL)
530
		rtnl_kfree_skbs(skb, skb);
L
Linus Torvalds 已提交
531 532
}

533 534 535 536 537 538
/*
 * When q->perturbation is changed, we rehash all queued skbs
 * to avoid OOO (Out Of Order) effects.
 * We dont use sfq_dequeue()/sfq_enqueue() because we dont want to change
 * counters.
 */
E
Eric Dumazet 已提交
539
static void sfq_rehash(struct Qdisc *sch)
540
{
E
Eric Dumazet 已提交
541
	struct sfq_sched_data *q = qdisc_priv(sch);
542 543 544 545
	struct sk_buff *skb;
	int i;
	struct sfq_slot *slot;
	struct sk_buff_head list;
E
Eric Dumazet 已提交
546
	int dropped = 0;
547
	unsigned int drop_len = 0;
548 549 550

	__skb_queue_head_init(&list);

E
Eric Dumazet 已提交
551
	for (i = 0; i < q->maxflows; i++) {
552 553 554 555 556 557 558 559
		slot = &q->slots[i];
		if (!slot->qlen)
			continue;
		while (slot->qlen) {
			skb = slot_dequeue_head(slot);
			sfq_dec(q, i);
			__skb_queue_tail(&list, skb);
		}
560 561
		slot->backlog = 0;
		red_set_vars(&slot->vars);
562 563 564 565 566 567 568 569 570 571 572
		q->ht[slot->hash] = SFQ_EMPTY_SLOT;
	}
	q->tail = NULL;

	while ((skb = __skb_dequeue(&list)) != NULL) {
		unsigned int hash = sfq_hash(q, skb);
		sfq_index x = q->ht[hash];

		slot = &q->slots[x];
		if (x == SFQ_EMPTY_SLOT) {
			x = q->dep[0].next; /* get a free slot */
E
Eric Dumazet 已提交
573
			if (x >= SFQ_MAX_FLOWS) {
574 575
drop:
				qdisc_qstats_backlog_dec(sch, skb);
576
				drop_len += qdisc_pkt_len(skb);
E
Eric Dumazet 已提交
577 578 579 580
				kfree_skb(skb);
				dropped++;
				continue;
			}
581 582 583 584
			q->ht[hash] = x;
			slot = &q->slots[x];
			slot->hash = hash;
		}
E
Eric Dumazet 已提交
585 586
		if (slot->qlen >= q->maxdepth)
			goto drop;
587
		slot_queue_add(slot, skb);
588 589 590 591 592
		if (q->red_parms)
			slot->vars.qavg = red_calc_qavg(q->red_parms,
							&slot->vars,
							slot->backlog);
		slot->backlog += qdisc_pkt_len(skb);
593 594 595 596 597 598 599 600 601 602 603 604
		sfq_inc(q, x);
		if (slot->qlen == 1) {		/* The flow is new */
			if (q->tail == NULL) {	/* It is the first flow */
				slot->next = x;
			} else {
				slot->next = q->tail->next;
				q->tail->next = x;
			}
			q->tail = slot;
			slot->allot = q->scaled_quantum;
		}
	}
E
Eric Dumazet 已提交
605
	sch->q.qlen -= dropped;
606
	qdisc_tree_reduce_backlog(sch, dropped, drop_len);
607 608
}

609
static void sfq_perturbation(struct timer_list *t)
L
Linus Torvalds 已提交
610
{
611 612
	struct sfq_sched_data *q = from_timer(q, t, perturb_timer);
	struct Qdisc *sch = q->sch;
613
	spinlock_t *root_lock = qdisc_lock(qdisc_root_sleeping(sch));
614
	siphash_key_t nkey;
L
Linus Torvalds 已提交
615

616
	get_random_bytes(&nkey, sizeof(nkey));
617
	spin_lock(root_lock);
618
	q->perturbation = nkey;
619
	if (!q->filter_list && q->tail)
E
Eric Dumazet 已提交
620
		sfq_rehash(sch);
621
	spin_unlock(root_lock);
L
Linus Torvalds 已提交
622

623 624
	if (q->perturb_period)
		mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
L
Linus Torvalds 已提交
625 626
}

627
static int sfq_change(struct Qdisc *sch, struct nlattr *opt)
L
Linus Torvalds 已提交
628 629
{
	struct sfq_sched_data *q = qdisc_priv(sch);
630
	struct tc_sfq_qopt *ctl = nla_data(opt);
E
Eric Dumazet 已提交
631
	struct tc_sfq_qopt_v1 *ctl_v1 = NULL;
632
	unsigned int qlen, dropped = 0;
633
	struct red_parms *p = NULL;
634 635
	struct sk_buff *to_free = NULL;
	struct sk_buff *tail = NULL;
L
Linus Torvalds 已提交
636

637
	if (opt->nla_len < nla_attr_size(sizeof(*ctl)))
L
Linus Torvalds 已提交
638
		return -EINVAL;
E
Eric Dumazet 已提交
639 640
	if (opt->nla_len >= nla_attr_size(sizeof(*ctl_v1)))
		ctl_v1 = nla_data(opt);
S
stephen hemminger 已提交
641 642 643
	if (ctl->divisor &&
	    (!is_power_of_2(ctl->divisor) || ctl->divisor > 65536))
		return -EINVAL;
644 645 646
	if (ctl_v1 && !red_check_params(ctl_v1->qth_min, ctl_v1->qth_max,
					ctl_v1->Wlog))
		return -EINVAL;
647 648 649 650 651
	if (ctl_v1 && ctl_v1->qth_min) {
		p = kmalloc(sizeof(*p), GFP_KERNEL);
		if (!p)
			return -ENOMEM;
	}
L
Linus Torvalds 已提交
652
	sch_tree_lock(sch);
E
Eric Dumazet 已提交
653 654 655 656
	if (ctl->quantum) {
		q->quantum = ctl->quantum;
		q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
	}
657
	q->perturb_period = ctl->perturb_period * HZ;
E
Eric Dumazet 已提交
658 659 660
	if (ctl->flows)
		q->maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
	if (ctl->divisor) {
661
		q->divisor = ctl->divisor;
E
Eric Dumazet 已提交
662 663 664 665 666
		q->maxflows = min_t(u32, q->maxflows, q->divisor);
	}
	if (ctl_v1) {
		if (ctl_v1->depth)
			q->maxdepth = min_t(u32, ctl_v1->depth, SFQ_MAX_DEPTH);
667 668 669 670 671 672 673 674 675 676
		if (p) {
			swap(q->red_parms, p);
			red_set_parms(q->red_parms,
				      ctl_v1->qth_min, ctl_v1->qth_max,
				      ctl_v1->Wlog,
				      ctl_v1->Plog, ctl_v1->Scell_log,
				      NULL,
				      ctl_v1->max_P);
		}
		q->flags = ctl_v1->flags;
E
Eric Dumazet 已提交
677 678 679 680 681 682 683
		q->headdrop = ctl_v1->headdrop;
	}
	if (ctl->limit) {
		q->limit = min_t(u32, ctl->limit, q->maxdepth * q->maxflows);
		q->maxflows = min_t(u32, q->maxflows, q->limit);
	}

684
	qlen = sch->q.qlen;
685 686 687 688 689 690 691
	while (sch->q.qlen > q->limit) {
		dropped += sfq_drop(sch, &to_free);
		if (!tail)
			tail = to_free;
	}

	rtnl_kfree_skbs(to_free, tail);
692
	qdisc_tree_reduce_backlog(sch, qlen - sch->q.qlen, dropped);
L
Linus Torvalds 已提交
693 694 695

	del_timer(&q->perturb_timer);
	if (q->perturb_period) {
696
		mod_timer(&q->perturb_timer, jiffies + q->perturb_period);
697
		get_random_bytes(&q->perturbation, sizeof(q->perturbation));
L
Linus Torvalds 已提交
698 699
	}
	sch_tree_unlock(sch);
700
	kfree(p);
L
Linus Torvalds 已提交
701 702 703
	return 0;
}

704 705
static void *sfq_alloc(size_t sz)
{
706
	return  kvmalloc(sz, GFP_KERNEL);
707 708 709 710
}

static void sfq_free(void *addr)
{
W
WANG Cong 已提交
711
	kvfree(addr);
712 713 714 715 716 717
}

static void sfq_destroy(struct Qdisc *sch)
{
	struct sfq_sched_data *q = qdisc_priv(sch);

718
	tcf_block_put(q->block);
719 720 721
	q->perturb_period = 0;
	del_timer_sync(&q->perturb_timer);
	sfq_free(q->ht);
E
Eric Dumazet 已提交
722
	sfq_free(q->slots);
723
	kfree(q->red_parms);
724 725
}

726 727
static int sfq_init(struct Qdisc *sch, struct nlattr *opt,
		    struct netlink_ext_ack *extack)
L
Linus Torvalds 已提交
728 729 730
{
	struct sfq_sched_data *q = qdisc_priv(sch);
	int i;
731 732
	int err;

733
	q->sch = sch;
734
	timer_setup(&q->perturb_timer, sfq_perturbation, TIMER_DEFERRABLE);
735

736
	err = tcf_block_get(&q->block, &q->filter_list, sch, extack);
737 738
	if (err)
		return err;
L
Linus Torvalds 已提交
739

E
Eric Dumazet 已提交
740 741 742
	for (i = 0; i < SFQ_MAX_DEPTH + 1; i++) {
		q->dep[i].next = i + SFQ_MAX_FLOWS;
		q->dep[i].prev = i + SFQ_MAX_FLOWS;
L
Linus Torvalds 已提交
743
	}
744

E
Eric Dumazet 已提交
745 746
	q->limit = SFQ_MAX_DEPTH;
	q->maxdepth = SFQ_MAX_DEPTH;
747 748
	q->cur_depth = 0;
	q->tail = NULL;
749
	q->divisor = SFQ_DEFAULT_HASH_DIVISOR;
E
Eric Dumazet 已提交
750
	q->maxflows = SFQ_DEFAULT_FLOWS;
751 752 753
	q->quantum = psched_mtu(qdisc_dev(sch));
	q->scaled_quantum = SFQ_ALLOT_SIZE(q->quantum);
	q->perturb_period = 0;
754
	get_random_bytes(&q->perturbation, sizeof(q->perturbation));
755 756

	if (opt) {
L
Linus Torvalds 已提交
757 758 759 760
		int err = sfq_change(sch, opt);
		if (err)
			return err;
	}
761

762
	q->ht = sfq_alloc(sizeof(q->ht[0]) * q->divisor);
E
Eric Dumazet 已提交
763 764
	q->slots = sfq_alloc(sizeof(q->slots[0]) * q->maxflows);
	if (!q->ht || !q->slots) {
765
		/* Note: sfq_destroy() will be called by our caller */
766
		return -ENOMEM;
767
	}
768

769 770 771
	for (i = 0; i < q->divisor; i++)
		q->ht[i] = SFQ_EMPTY_SLOT;

E
Eric Dumazet 已提交
772
	for (i = 0; i < q->maxflows; i++) {
E
Eric Dumazet 已提交
773
		slot_queue_init(&q->slots[i]);
L
Linus Torvalds 已提交
774
		sfq_link(q, i);
E
Eric Dumazet 已提交
775
	}
776 777 778 779
	if (q->limit >= 1)
		sch->flags |= TCQ_F_CAN_BYPASS;
	else
		sch->flags &= ~TCQ_F_CAN_BYPASS;
L
Linus Torvalds 已提交
780 781 782 783 784 785
	return 0;
}

static int sfq_dump(struct Qdisc *sch, struct sk_buff *skb)
{
	struct sfq_sched_data *q = qdisc_priv(sch);
786
	unsigned char *b = skb_tail_pointer(skb);
E
Eric Dumazet 已提交
787
	struct tc_sfq_qopt_v1 opt;
788
	struct red_parms *p = q->red_parms;
E
Eric Dumazet 已提交
789 790 791 792 793 794 795 796 797

	memset(&opt, 0, sizeof(opt));
	opt.v0.quantum	= q->quantum;
	opt.v0.perturb_period = q->perturb_period / HZ;
	opt.v0.limit	= q->limit;
	opt.v0.divisor	= q->divisor;
	opt.v0.flows	= q->maxflows;
	opt.depth	= q->maxdepth;
	opt.headdrop	= q->headdrop;
L
Linus Torvalds 已提交
798

799 800 801 802 803 804 805 806 807 808 809
	if (p) {
		opt.qth_min	= p->qth_min >> p->Wlog;
		opt.qth_max	= p->qth_max >> p->Wlog;
		opt.Wlog	= p->Wlog;
		opt.Plog	= p->Plog;
		opt.Scell_log	= p->Scell_log;
		opt.max_P	= p->max_P;
	}
	memcpy(&opt.stats, &q->stats, sizeof(opt.stats));
	opt.flags	= q->flags;

810 811
	if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
		goto nla_put_failure;
L
Linus Torvalds 已提交
812 813 814

	return skb->len;

815
nla_put_failure:
816
	nlmsg_trim(skb, b);
L
Linus Torvalds 已提交
817 818 819
	return -1;
}

820 821 822 823 824
static struct Qdisc *sfq_leaf(struct Qdisc *sch, unsigned long arg)
{
	return NULL;
}

825
static unsigned long sfq_find(struct Qdisc *sch, u32 classid)
826 827 828 829
{
	return 0;
}

830 831 832 833 834 835
static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent,
			      u32 classid)
{
	return 0;
}

836
static void sfq_unbind(struct Qdisc *q, unsigned long cl)
837 838 839
{
}

840 841
static struct tcf_block *sfq_tcf_block(struct Qdisc *sch, unsigned long cl,
				       struct netlink_ext_ack *extack)
842 843 844 845 846
{
	struct sfq_sched_data *q = qdisc_priv(sch);

	if (cl)
		return NULL;
847
	return q->block;
848 849
}

850 851 852 853 854 855 856 857 858 859 860
static int sfq_dump_class(struct Qdisc *sch, unsigned long cl,
			  struct sk_buff *skb, struct tcmsg *tcm)
{
	tcm->tcm_handle |= TC_H_MIN(cl);
	return 0;
}

static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
				struct gnet_dump *d)
{
	struct sfq_sched_data *q = qdisc_priv(sch);
E
Eric Dumazet 已提交
861 862 863
	sfq_index idx = q->ht[cl - 1];
	struct gnet_stats_queue qs = { 0 };
	struct tc_sfq_xstats xstats = { 0 };
864

E
Eric Dumazet 已提交
865 866
	if (idx != SFQ_EMPTY_SLOT) {
		const struct sfq_slot *slot = &q->slots[idx];
867

868
		xstats.allot = slot->allot << SFQ_ALLOT_SHIFT;
E
Eric Dumazet 已提交
869
		qs.qlen = slot->qlen;
870
		qs.backlog = slot->backlog;
E
Eric Dumazet 已提交
871
	}
872
	if (gnet_stats_copy_queue(d, NULL, &qs, qs.qlen) < 0)
873 874 875 876
		return -1;
	return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
}

877 878
static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
{
879 880 881 882 883 884
	struct sfq_sched_data *q = qdisc_priv(sch);
	unsigned int i;

	if (arg->stop)
		return;

885
	for (i = 0; i < q->divisor; i++) {
886
		if (q->ht[i] == SFQ_EMPTY_SLOT ||
887 888 889 890 891 892 893 894 895 896
		    arg->count < arg->skip) {
			arg->count++;
			continue;
		}
		if (arg->fn(sch, i + 1, arg) < 0) {
			arg->stop = 1;
			break;
		}
		arg->count++;
	}
897 898 899
}

static const struct Qdisc_class_ops sfq_class_ops = {
900
	.leaf		=	sfq_leaf,
901
	.find		=	sfq_find,
902
	.tcf_block	=	sfq_tcf_block,
903
	.bind_tcf	=	sfq_bind,
904
	.unbind_tcf	=	sfq_unbind,
905 906
	.dump		=	sfq_dump_class,
	.dump_stats	=	sfq_dump_class_stats,
907 908 909
	.walk		=	sfq_walk,
};

910
static struct Qdisc_ops sfq_qdisc_ops __read_mostly = {
911
	.cl_ops		=	&sfq_class_ops,
L
Linus Torvalds 已提交
912 913 914 915
	.id		=	"sfq",
	.priv_size	=	sizeof(struct sfq_sched_data),
	.enqueue	=	sfq_enqueue,
	.dequeue	=	sfq_dequeue,
916
	.peek		=	qdisc_peek_dequeued,
L
Linus Torvalds 已提交
917 918 919 920 921 922 923 924 925 926 927 928
	.init		=	sfq_init,
	.reset		=	sfq_reset,
	.destroy	=	sfq_destroy,
	.change		=	NULL,
	.dump		=	sfq_dump,
	.owner		=	THIS_MODULE,
};

static int __init sfq_module_init(void)
{
	return register_qdisc(&sfq_qdisc_ops);
}
929
static void __exit sfq_module_exit(void)
L
Linus Torvalds 已提交
930 931 932 933 934 935
{
	unregister_qdisc(&sfq_qdisc_ops);
}
module_init(sfq_module_init)
module_exit(sfq_module_exit)
MODULE_LICENSE("GPL");