@@ -30,64 +30,65 @@ struct pie_sched_data {
30
30
struct Qdisc * sch ;
31
31
};
32
32
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 )
34
35
{
35
- struct pie_sched_data * q = qdisc_priv (sch );
36
36
u64 rnd ;
37
- u64 local_prob = q -> vars . prob ;
37
+ u64 local_prob = vars -> prob ;
38
38
u32 mtu = psched_mtu (qdisc_dev (sch ));
39
39
40
40
/* If there is still burst allowance left skip random early drop */
41
- if (q -> vars . burst_time > 0 )
41
+ if (vars -> burst_time > 0 )
42
42
return false;
43
43
44
44
/* If current delay is less than half of target, and
45
45
* if drop prob is low already, disable early_drop
46
46
*/
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 ))
49
49
return false;
50
50
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 ,
52
52
* similar to min_th in RED
53
53
*/
54
- if (sch -> qstats . backlog < 2 * mtu )
54
+ if (qlen < 2 * mtu )
55
55
return false;
56
56
57
57
/* If bytemode is turned on, use packet size to compute new
58
58
* probablity. Smaller packets will have lower drop prob in this case
59
59
*/
60
- if (q -> params . bytemode && packet_size <= mtu )
60
+ if (params -> bytemode && packet_size <= mtu )
61
61
local_prob = (u64 )packet_size * div_u64 (local_prob , mtu );
62
62
else
63
- local_prob = q -> vars . prob ;
63
+ local_prob = vars -> prob ;
64
64
65
65
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 ;
68
68
}
69
69
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 ++ ;
72
72
73
- q -> vars . accu_prob += local_prob ;
73
+ vars -> accu_prob += local_prob ;
74
74
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 )
77
77
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 )
80
80
return true;
81
81
82
82
prandom_bytes (& rnd , 8 );
83
83
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 ;
86
86
return true;
87
87
}
88
88
89
89
return false;
90
90
}
91
+ EXPORT_SYMBOL_GPL (pie_drop_early );
91
92
92
93
static int pie_qdisc_enqueue (struct sk_buff * skb , struct Qdisc * sch ,
93
94
struct sk_buff * * to_free )
@@ -100,7 +101,8 @@ static int pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
100
101
goto out ;
101
102
}
102
103
103
- if (!drop_early (sch , skb -> len )) {
104
+ if (!pie_drop_early (sch , & q -> params , & q -> vars , sch -> qstats .backlog ,
105
+ skb -> len )) {
104
106
enqueue = true;
105
107
} else if (q -> params .ecn && (q -> vars .prob <= MAX_PROB / 10 ) &&
106
108
INET_ECN_set_ce (skb )) {
@@ -212,26 +214,25 @@ static int pie_change(struct Qdisc *sch, struct nlattr *opt,
212
214
return 0 ;
213
215
}
214
216
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 )
216
219
{
217
- struct pie_sched_data * q = qdisc_priv (sch );
218
- int qlen = sch -> qstats .backlog ; /* current queue size in bytes */
219
220
psched_time_t now = psched_get_time ();
220
221
u32 dtime = 0 ;
221
222
222
223
/* If dq_rate_estimator is disabled, calculate qdelay using the
223
224
* packet timestamp.
224
225
*/
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 );
227
228
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 ;
230
231
231
- q -> vars . dq_tstamp = now ;
232
+ vars -> dq_tstamp = now ;
232
233
233
234
if (qlen == 0 )
234
- q -> vars . qdelay = 0 ;
235
+ vars -> qdelay = 0 ;
235
236
236
237
if (dtime == 0 )
237
238
return ;
@@ -243,9 +244,9 @@ static void pie_process_dequeue(struct Qdisc *sch, struct sk_buff *skb)
243
244
* we have enough packets to calculate the drain rate. Save
244
245
* current time as dq_tstamp and start measurement cycle.
245
246
*/
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 ;
249
250
}
250
251
251
252
/* 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)
257
258
* in bytes, time difference in psched_time, hence rate is in
258
259
* bytes/psched_time.
259
260
*/
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 ;
262
263
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 ;
265
266
266
- dtime = now - q -> vars . dq_tstamp ;
267
+ dtime = now - vars -> dq_tstamp ;
267
268
268
269
if (dtime == 0 )
269
270
return ;
270
271
271
272
count = count / dtime ;
272
273
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 ;
275
276
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 );
279
280
280
281
/* If the queue has receded below the threshold, we hold
281
282
* on to the last drain rate calculated, else we reset
282
283
* dq_count to 0 to re-enter the if block when the next
283
284
* packet is dequeued
284
285
*/
285
286
if (qlen < QUEUE_THRESHOLD ) {
286
- q -> vars . dq_count = DQCOUNT_INVALID ;
287
+ vars -> dq_count = DQCOUNT_INVALID ;
287
288
} 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 ();
290
291
}
291
292
292
293
goto burst_allowance_reduction ;
@@ -296,18 +297,18 @@ static void pie_process_dequeue(struct Qdisc *sch, struct sk_buff *skb)
296
297
return ;
297
298
298
299
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 ;
302
303
else
303
- q -> vars . burst_time = 0 ;
304
+ vars -> burst_time = 0 ;
304
305
}
305
306
}
307
+ EXPORT_SYMBOL_GPL (pie_process_dequeue );
306
308
307
- static void calculate_probability (struct Qdisc * sch )
309
+ void pie_calculate_probability (struct pie_params * params , struct pie_vars * vars ,
310
+ u32 qlen )
308
311
{
309
- struct pie_sched_data * q = qdisc_priv (sch );
310
- u32 qlen = sch -> qstats .backlog ; /* queue size in bytes */
311
312
psched_time_t qdelay = 0 ; /* in pschedtime */
312
313
psched_time_t qdelay_old = 0 ; /* in pschedtime */
313
314
s64 delta = 0 ; /* determines the change in probability */
@@ -316,17 +317,17 @@ static void calculate_probability(struct Qdisc *sch)
316
317
u32 power ;
317
318
bool update_prob = true;
318
319
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 ;
322
323
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 ;
325
326
else
326
327
qdelay = 0 ;
327
328
} else {
328
- qdelay = q -> vars . qdelay ;
329
- qdelay_old = q -> vars . qdelay_old ;
329
+ qdelay = vars -> qdelay ;
330
+ qdelay_old = vars -> qdelay_old ;
330
331
}
331
332
332
333
/* 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)
342
343
* probability. alpha/beta are updated locally below by scaling down
343
344
* by 16 to come to 0-2 range.
344
345
*/
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 ;
347
348
348
349
/* We scale alpha and beta differently depending on how heavy the
349
350
* congestion is. Please see RFC 8033 for details.
350
351
*/
351
- if (q -> vars . prob < MAX_PROB / 10 ) {
352
+ if (vars -> prob < MAX_PROB / 10 ) {
352
353
alpha >>= 1 ;
353
354
beta >>= 1 ;
354
355
355
356
power = 100 ;
356
- while (q -> vars . prob < div_u64 (MAX_PROB , power ) &&
357
+ while (vars -> prob < div_u64 (MAX_PROB , power ) &&
357
358
power <= 1000000 ) {
358
359
alpha >>= 2 ;
359
360
beta >>= 2 ;
@@ -362,14 +363,14 @@ static void calculate_probability(struct Qdisc *sch)
362
363
}
363
364
364
365
/* 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 );
366
367
delta += beta * (u64 )(qdelay - qdelay_old );
367
368
368
- oldprob = q -> vars . prob ;
369
+ oldprob = vars -> prob ;
369
370
370
371
/* to ensure we increase probability in steps of no more than 2% */
371
372
if (delta > (s64 )(MAX_PROB / (100 / 2 )) &&
372
- q -> vars . prob >= MAX_PROB / 10 )
373
+ vars -> prob >= MAX_PROB / 10 )
373
374
delta = (MAX_PROB / 100 ) * 2 ;
374
375
375
376
/* Non-linear drop:
@@ -380,12 +381,12 @@ static void calculate_probability(struct Qdisc *sch)
380
381
if (qdelay > (PSCHED_NS2TICKS (250 * NSEC_PER_MSEC )))
381
382
delta += MAX_PROB / (100 / 2 );
382
383
383
- q -> vars . prob += delta ;
384
+ vars -> prob += delta ;
384
385
385
386
if (delta > 0 ) {
386
387
/* prevent overflow */
387
- if (q -> vars . prob < oldprob ) {
388
- q -> vars . prob = MAX_PROB ;
388
+ if (vars -> prob < oldprob ) {
389
+ vars -> prob = MAX_PROB ;
389
390
/* Prevent normalization error. If probability is at
390
391
* maximum value already, we normalize it here, and
391
392
* skip the check to do a non-linear drop in the next
@@ -395,8 +396,8 @@ static void calculate_probability(struct Qdisc *sch)
395
396
}
396
397
} else {
397
398
/* prevent underflow */
398
- if (q -> vars . prob > oldprob )
399
- q -> vars . prob = 0 ;
399
+ if (vars -> prob > oldprob )
400
+ vars -> prob = 0 ;
400
401
}
401
402
402
403
/* Non-linear drop in probability: Reduce drop probability quickly if
@@ -405,27 +406,28 @@ static void calculate_probability(struct Qdisc *sch)
405
406
406
407
if (qdelay == 0 && qdelay_old == 0 && update_prob )
407
408
/* Reduce drop probability to 98.4% */
408
- q -> vars . prob -= q -> vars . prob / 64u ;
409
+ vars -> prob -= vars -> prob / 64 ;
409
410
410
- q -> vars . qdelay = qdelay ;
411
- q -> vars . qlen_old = qlen ;
411
+ vars -> qdelay = qdelay ;
412
+ vars -> qlen_old = qlen ;
412
413
413
414
/* We restart the measurement cycle if the following conditions are met
414
415
* 1. If the delay has been low for 2 consecutive Tupdate periods
415
416
* 2. Calculated drop probability is zero
416
417
* 3. If average dq_rate_estimator is enabled, we have atleast one
417
418
* estimate for the avg_dq_rate ie., is a non-zero value
418
419
*/
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 );
424
425
}
425
426
426
- if (!q -> params . dq_rate_estimator )
427
- q -> vars . qdelay_old = qdelay ;
427
+ if (!params -> dq_rate_estimator )
428
+ vars -> qdelay_old = qdelay ;
428
429
}
430
+ EXPORT_SYMBOL_GPL (pie_calculate_probability );
429
431
430
432
static void pie_timer (struct timer_list * t )
431
433
{
@@ -434,7 +436,7 @@ static void pie_timer(struct timer_list *t)
434
436
spinlock_t * root_lock = qdisc_lock (qdisc_root_sleeping (sch ));
435
437
436
438
spin_lock (root_lock );
437
- calculate_probability ( sch );
439
+ pie_calculate_probability ( & q -> params , & q -> vars , sch -> qstats . backlog );
438
440
439
441
/* reset the timer to fire after 'tupdate'. tupdate is in jiffies. */
440
442
if (q -> params .tupdate )
@@ -523,12 +525,13 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
523
525
524
526
static struct sk_buff * pie_qdisc_dequeue (struct Qdisc * sch )
525
527
{
528
+ struct pie_sched_data * q = qdisc_priv (sch );
526
529
struct sk_buff * skb = qdisc_dequeue_head (sch );
527
530
528
531
if (!skb )
529
532
return NULL ;
530
533
531
- pie_process_dequeue (sch , skb );
534
+ pie_process_dequeue (skb , & q -> params , & q -> vars , sch -> qstats . backlog );
532
535
return skb ;
533
536
}
534
537
0 commit comments