Skip to content

Commit 5205ea0

Browse files
mohittahilianidavem330
authored andcommitted
net: sched: pie: export symbols to be reused by FQ-PIE
This patch makes the drop_early(), calculate_probability() and pie_process_dequeue() functions generic enough to be used by both PIE and FQ-PIE (to be added in a future commit). The major change here is in the way the functions take in arguments. This patch exports these functions and makes FQ-PIE dependent on sch_pie. Signed-off-by: Mohit P. Tahiliani <[email protected]> Signed-off-by: Leslie Monis <[email protected]> Signed-off-by: Gautam Ramakrishnan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 00ea2fb commit 5205ea0

File tree

2 files changed

+97
-85
lines changed

2 files changed

+97
-85
lines changed

include/net/pie.h

+9
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,13 @@ static inline void pie_set_enqueue_time(struct sk_buff *skb)
124124
get_pie_cb(skb)->enqueue_time = psched_get_time();
125125
}
126126

127+
bool pie_drop_early(struct Qdisc *sch, struct pie_params *params,
128+
struct pie_vars *vars, u32 qlen, u32 packet_size);
129+
130+
void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params,
131+
struct pie_vars *vars, u32 qlen);
132+
133+
void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars,
134+
u32 qlen);
135+
127136
#endif

net/sched/sch_pie.c

+88-85
Original file line numberDiff line numberDiff line change
@@ -30,64 +30,65 @@ struct pie_sched_data {
3030
struct Qdisc *sch;
3131
};
3232

33-
static bool drop_early(struct Qdisc *sch, u32 packet_size)
33+
bool pie_drop_early(struct Qdisc *sch, struct pie_params *params,
34+
struct pie_vars *vars, u32 qlen, u32 packet_size)
3435
{
35-
struct pie_sched_data *q = qdisc_priv(sch);
3636
u64 rnd;
37-
u64 local_prob = q->vars.prob;
37+
u64 local_prob = vars->prob;
3838
u32 mtu = psched_mtu(qdisc_dev(sch));
3939

4040
/* If there is still burst allowance left skip random early drop */
41-
if (q->vars.burst_time > 0)
41+
if (vars->burst_time > 0)
4242
return false;
4343

4444
/* If current delay is less than half of target, and
4545
* if drop prob is low already, disable early_drop
4646
*/
47-
if ((q->vars.qdelay < q->params.target / 2) &&
48-
(q->vars.prob < MAX_PROB / 5))
47+
if ((vars->qdelay < params->target / 2) &&
48+
(vars->prob < MAX_PROB / 5))
4949
return false;
5050

51-
/* If we have fewer than 2 mtu-sized packets, disable drop_early,
51+
/* If we have fewer than 2 mtu-sized packets, disable pie_drop_early,
5252
* similar to min_th in RED
5353
*/
54-
if (sch->qstats.backlog < 2 * mtu)
54+
if (qlen < 2 * mtu)
5555
return false;
5656

5757
/* If bytemode is turned on, use packet size to compute new
5858
* probablity. Smaller packets will have lower drop prob in this case
5959
*/
60-
if (q->params.bytemode && packet_size <= mtu)
60+
if (params->bytemode && packet_size <= mtu)
6161
local_prob = (u64)packet_size * div_u64(local_prob, mtu);
6262
else
63-
local_prob = q->vars.prob;
63+
local_prob = vars->prob;
6464

6565
if (local_prob == 0) {
66-
q->vars.accu_prob = 0;
67-
q->vars.accu_prob_overflows = 0;
66+
vars->accu_prob = 0;
67+
vars->accu_prob_overflows = 0;
6868
}
6969

70-
if (local_prob > MAX_PROB - q->vars.accu_prob)
71-
q->vars.accu_prob_overflows++;
70+
if (local_prob > MAX_PROB - vars->accu_prob)
71+
vars->accu_prob_overflows++;
7272

73-
q->vars.accu_prob += local_prob;
73+
vars->accu_prob += local_prob;
7474

75-
if (q->vars.accu_prob_overflows == 0 &&
76-
q->vars.accu_prob < (MAX_PROB / 100) * 85)
75+
if (vars->accu_prob_overflows == 0 &&
76+
vars->accu_prob < (MAX_PROB / 100) * 85)
7777
return false;
78-
if (q->vars.accu_prob_overflows == 8 &&
79-
q->vars.accu_prob >= MAX_PROB / 2)
78+
if (vars->accu_prob_overflows == 8 &&
79+
vars->accu_prob >= MAX_PROB / 2)
8080
return true;
8181

8282
prandom_bytes(&rnd, 8);
8383
if (rnd < local_prob) {
84-
q->vars.accu_prob = 0;
85-
q->vars.accu_prob_overflows = 0;
84+
vars->accu_prob = 0;
85+
vars->accu_prob_overflows = 0;
8686
return true;
8787
}
8888

8989
return false;
9090
}
91+
EXPORT_SYMBOL_GPL(pie_drop_early);
9192

9293
static int pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
9394
struct sk_buff **to_free)
@@ -100,7 +101,8 @@ static int pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
100101
goto out;
101102
}
102103

103-
if (!drop_early(sch, skb->len)) {
104+
if (!pie_drop_early(sch, &q->params, &q->vars, sch->qstats.backlog,
105+
skb->len)) {
104106
enqueue = true;
105107
} else if (q->params.ecn && (q->vars.prob <= MAX_PROB / 10) &&
106108
INET_ECN_set_ce(skb)) {
@@ -212,26 +214,25 @@ static int pie_change(struct Qdisc *sch, struct nlattr *opt,
212214
return 0;
213215
}
214216

215-
static void pie_process_dequeue(struct Qdisc *sch, struct sk_buff *skb)
217+
void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params,
218+
struct pie_vars *vars, u32 qlen)
216219
{
217-
struct pie_sched_data *q = qdisc_priv(sch);
218-
int qlen = sch->qstats.backlog; /* current queue size in bytes */
219220
psched_time_t now = psched_get_time();
220221
u32 dtime = 0;
221222

222223
/* If dq_rate_estimator is disabled, calculate qdelay using the
223224
* packet timestamp.
224225
*/
225-
if (!q->params.dq_rate_estimator) {
226-
q->vars.qdelay = now - pie_get_enqueue_time(skb);
226+
if (!params->dq_rate_estimator) {
227+
vars->qdelay = now - pie_get_enqueue_time(skb);
227228

228-
if (q->vars.dq_tstamp != DTIME_INVALID)
229-
dtime = now - q->vars.dq_tstamp;
229+
if (vars->dq_tstamp != DTIME_INVALID)
230+
dtime = now - vars->dq_tstamp;
230231

231-
q->vars.dq_tstamp = now;
232+
vars->dq_tstamp = now;
232233

233234
if (qlen == 0)
234-
q->vars.qdelay = 0;
235+
vars->qdelay = 0;
235236

236237
if (dtime == 0)
237238
return;
@@ -243,9 +244,9 @@ static void pie_process_dequeue(struct Qdisc *sch, struct sk_buff *skb)
243244
* we have enough packets to calculate the drain rate. Save
244245
* current time as dq_tstamp and start measurement cycle.
245246
*/
246-
if (qlen >= QUEUE_THRESHOLD && q->vars.dq_count == DQCOUNT_INVALID) {
247-
q->vars.dq_tstamp = psched_get_time();
248-
q->vars.dq_count = 0;
247+
if (qlen >= QUEUE_THRESHOLD && vars->dq_count == DQCOUNT_INVALID) {
248+
vars->dq_tstamp = psched_get_time();
249+
vars->dq_count = 0;
249250
}
250251

251252
/* Calculate the average drain rate from this value. If queue length
@@ -257,36 +258,36 @@ static void pie_process_dequeue(struct Qdisc *sch, struct sk_buff *skb)
257258
* in bytes, time difference in psched_time, hence rate is in
258259
* bytes/psched_time.
259260
*/
260-
if (q->vars.dq_count != DQCOUNT_INVALID) {
261-
q->vars.dq_count += skb->len;
261+
if (vars->dq_count != DQCOUNT_INVALID) {
262+
vars->dq_count += skb->len;
262263

263-
if (q->vars.dq_count >= QUEUE_THRESHOLD) {
264-
u32 count = q->vars.dq_count << PIE_SCALE;
264+
if (vars->dq_count >= QUEUE_THRESHOLD) {
265+
u32 count = vars->dq_count << PIE_SCALE;
265266

266-
dtime = now - q->vars.dq_tstamp;
267+
dtime = now - vars->dq_tstamp;
267268

268269
if (dtime == 0)
269270
return;
270271

271272
count = count / dtime;
272273

273-
if (q->vars.avg_dq_rate == 0)
274-
q->vars.avg_dq_rate = count;
274+
if (vars->avg_dq_rate == 0)
275+
vars->avg_dq_rate = count;
275276
else
276-
q->vars.avg_dq_rate =
277-
(q->vars.avg_dq_rate -
278-
(q->vars.avg_dq_rate >> 3)) + (count >> 3);
277+
vars->avg_dq_rate =
278+
(vars->avg_dq_rate -
279+
(vars->avg_dq_rate >> 3)) + (count >> 3);
279280

280281
/* If the queue has receded below the threshold, we hold
281282
* on to the last drain rate calculated, else we reset
282283
* dq_count to 0 to re-enter the if block when the next
283284
* packet is dequeued
284285
*/
285286
if (qlen < QUEUE_THRESHOLD) {
286-
q->vars.dq_count = DQCOUNT_INVALID;
287+
vars->dq_count = DQCOUNT_INVALID;
287288
} else {
288-
q->vars.dq_count = 0;
289-
q->vars.dq_tstamp = psched_get_time();
289+
vars->dq_count = 0;
290+
vars->dq_tstamp = psched_get_time();
290291
}
291292

292293
goto burst_allowance_reduction;
@@ -296,18 +297,18 @@ static void pie_process_dequeue(struct Qdisc *sch, struct sk_buff *skb)
296297
return;
297298

298299
burst_allowance_reduction:
299-
if (q->vars.burst_time > 0) {
300-
if (q->vars.burst_time > dtime)
301-
q->vars.burst_time -= dtime;
300+
if (vars->burst_time > 0) {
301+
if (vars->burst_time > dtime)
302+
vars->burst_time -= dtime;
302303
else
303-
q->vars.burst_time = 0;
304+
vars->burst_time = 0;
304305
}
305306
}
307+
EXPORT_SYMBOL_GPL(pie_process_dequeue);
306308

307-
static void calculate_probability(struct Qdisc *sch)
309+
void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars,
310+
u32 qlen)
308311
{
309-
struct pie_sched_data *q = qdisc_priv(sch);
310-
u32 qlen = sch->qstats.backlog; /* queue size in bytes */
311312
psched_time_t qdelay = 0; /* in pschedtime */
312313
psched_time_t qdelay_old = 0; /* in pschedtime */
313314
s64 delta = 0; /* determines the change in probability */
@@ -316,17 +317,17 @@ static void calculate_probability(struct Qdisc *sch)
316317
u32 power;
317318
bool update_prob = true;
318319

319-
if (q->params.dq_rate_estimator) {
320-
qdelay_old = q->vars.qdelay;
321-
q->vars.qdelay_old = q->vars.qdelay;
320+
if (params->dq_rate_estimator) {
321+
qdelay_old = vars->qdelay;
322+
vars->qdelay_old = vars->qdelay;
322323

323-
if (q->vars.avg_dq_rate > 0)
324-
qdelay = (qlen << PIE_SCALE) / q->vars.avg_dq_rate;
324+
if (vars->avg_dq_rate > 0)
325+
qdelay = (qlen << PIE_SCALE) / vars->avg_dq_rate;
325326
else
326327
qdelay = 0;
327328
} else {
328-
qdelay = q->vars.qdelay;
329-
qdelay_old = q->vars.qdelay_old;
329+
qdelay = vars->qdelay;
330+
qdelay_old = vars->qdelay_old;
330331
}
331332

332333
/* If qdelay is zero and qlen is not, it means qlen is very small,
@@ -342,18 +343,18 @@ static void calculate_probability(struct Qdisc *sch)
342343
* probability. alpha/beta are updated locally below by scaling down
343344
* by 16 to come to 0-2 range.
344345
*/
345-
alpha = ((u64)q->params.alpha * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
346-
beta = ((u64)q->params.beta * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
346+
alpha = ((u64)params->alpha * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
347+
beta = ((u64)params->beta * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
347348

348349
/* We scale alpha and beta differently depending on how heavy the
349350
* congestion is. Please see RFC 8033 for details.
350351
*/
351-
if (q->vars.prob < MAX_PROB / 10) {
352+
if (vars->prob < MAX_PROB / 10) {
352353
alpha >>= 1;
353354
beta >>= 1;
354355

355356
power = 100;
356-
while (q->vars.prob < div_u64(MAX_PROB, power) &&
357+
while (vars->prob < div_u64(MAX_PROB, power) &&
357358
power <= 1000000) {
358359
alpha >>= 2;
359360
beta >>= 2;
@@ -362,14 +363,14 @@ static void calculate_probability(struct Qdisc *sch)
362363
}
363364

364365
/* alpha and beta should be between 0 and 32, in multiples of 1/16 */
365-
delta += alpha * (u64)(qdelay - q->params.target);
366+
delta += alpha * (u64)(qdelay - params->target);
366367
delta += beta * (u64)(qdelay - qdelay_old);
367368

368-
oldprob = q->vars.prob;
369+
oldprob = vars->prob;
369370

370371
/* to ensure we increase probability in steps of no more than 2% */
371372
if (delta > (s64)(MAX_PROB / (100 / 2)) &&
372-
q->vars.prob >= MAX_PROB / 10)
373+
vars->prob >= MAX_PROB / 10)
373374
delta = (MAX_PROB / 100) * 2;
374375

375376
/* Non-linear drop:
@@ -380,12 +381,12 @@ static void calculate_probability(struct Qdisc *sch)
380381
if (qdelay > (PSCHED_NS2TICKS(250 * NSEC_PER_MSEC)))
381382
delta += MAX_PROB / (100 / 2);
382383

383-
q->vars.prob += delta;
384+
vars->prob += delta;
384385

385386
if (delta > 0) {
386387
/* prevent overflow */
387-
if (q->vars.prob < oldprob) {
388-
q->vars.prob = MAX_PROB;
388+
if (vars->prob < oldprob) {
389+
vars->prob = MAX_PROB;
389390
/* Prevent normalization error. If probability is at
390391
* maximum value already, we normalize it here, and
391392
* skip the check to do a non-linear drop in the next
@@ -395,8 +396,8 @@ static void calculate_probability(struct Qdisc *sch)
395396
}
396397
} else {
397398
/* prevent underflow */
398-
if (q->vars.prob > oldprob)
399-
q->vars.prob = 0;
399+
if (vars->prob > oldprob)
400+
vars->prob = 0;
400401
}
401402

402403
/* Non-linear drop in probability: Reduce drop probability quickly if
@@ -405,27 +406,28 @@ static void calculate_probability(struct Qdisc *sch)
405406

406407
if (qdelay == 0 && qdelay_old == 0 && update_prob)
407408
/* Reduce drop probability to 98.4% */
408-
q->vars.prob -= q->vars.prob / 64u;
409+
vars->prob -= vars->prob / 64;
409410

410-
q->vars.qdelay = qdelay;
411-
q->vars.qlen_old = qlen;
411+
vars->qdelay = qdelay;
412+
vars->qlen_old = qlen;
412413

413414
/* We restart the measurement cycle if the following conditions are met
414415
* 1. If the delay has been low for 2 consecutive Tupdate periods
415416
* 2. Calculated drop probability is zero
416417
* 3. If average dq_rate_estimator is enabled, we have atleast one
417418
* estimate for the avg_dq_rate ie., is a non-zero value
418419
*/
419-
if ((q->vars.qdelay < q->params.target / 2) &&
420-
(q->vars.qdelay_old < q->params.target / 2) &&
421-
q->vars.prob == 0 &&
422-
(!q->params.dq_rate_estimator || q->vars.avg_dq_rate > 0)) {
423-
pie_vars_init(&q->vars);
420+
if ((vars->qdelay < params->target / 2) &&
421+
(vars->qdelay_old < params->target / 2) &&
422+
vars->prob == 0 &&
423+
(!params->dq_rate_estimator || vars->avg_dq_rate > 0)) {
424+
pie_vars_init(vars);
424425
}
425426

426-
if (!q->params.dq_rate_estimator)
427-
q->vars.qdelay_old = qdelay;
427+
if (!params->dq_rate_estimator)
428+
vars->qdelay_old = qdelay;
428429
}
430+
EXPORT_SYMBOL_GPL(pie_calculate_probability);
429431

430432
static void pie_timer(struct timer_list *t)
431433
{
@@ -434,7 +436,7 @@ static void pie_timer(struct timer_list *t)
434436
spinlock_t *root_lock = qdisc_lock(qdisc_root_sleeping(sch));
435437

436438
spin_lock(root_lock);
437-
calculate_probability(sch);
439+
pie_calculate_probability(&q->params, &q->vars, sch->qstats.backlog);
438440

439441
/* reset the timer to fire after 'tupdate'. tupdate is in jiffies. */
440442
if (q->params.tupdate)
@@ -523,12 +525,13 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
523525

524526
static struct sk_buff *pie_qdisc_dequeue(struct Qdisc *sch)
525527
{
528+
struct pie_sched_data *q = qdisc_priv(sch);
526529
struct sk_buff *skb = qdisc_dequeue_head(sch);
527530

528531
if (!skb)
529532
return NULL;
530533

531-
pie_process_dequeue(sch, skb);
534+
pie_process_dequeue(skb, &q->params, &q->vars, sch->qstats.backlog);
532535
return skb;
533536
}
534537

0 commit comments

Comments
 (0)