22
22
23
23
#define QUEUE_THRESHOLD 16384
24
24
#define DQCOUNT_INVALID -1
25
+ #define DTIME_INVALID 0xffffffffffffffff
25
26
#define MAX_PROB 0xffffffffffffffff
26
27
#define PIE_SCALE 8
27
28
@@ -34,6 +35,7 @@ struct pie_params {
34
35
u32 beta ; /* and are used for shift relative to 1 */
35
36
bool ecn ; /* true if ecn is enabled */
36
37
bool bytemode ; /* to scale drop early prob based on pkt size */
38
+ u8 dq_rate_estimator ; /* to calculate delay using Little's law */
37
39
};
38
40
39
41
/* variables used */
@@ -77,11 +79,34 @@ static void pie_params_init(struct pie_params *params)
77
79
params -> target = PSCHED_NS2TICKS (15 * NSEC_PER_MSEC ); /* 15 ms */
78
80
params -> ecn = false;
79
81
params -> bytemode = false;
82
+ params -> dq_rate_estimator = false;
83
+ }
84
+
85
+ /* private skb vars */
86
+ struct pie_skb_cb {
87
+ psched_time_t enqueue_time ;
88
+ };
89
+
90
+ static struct pie_skb_cb * get_pie_cb (const struct sk_buff * skb )
91
+ {
92
+ qdisc_cb_private_validate (skb , sizeof (struct pie_skb_cb ));
93
+ return (struct pie_skb_cb * )qdisc_skb_cb (skb )-> data ;
94
+ }
95
+
96
+ static psched_time_t pie_get_enqueue_time (const struct sk_buff * skb )
97
+ {
98
+ return get_pie_cb (skb )-> enqueue_time ;
99
+ }
100
+
101
+ static void pie_set_enqueue_time (struct sk_buff * skb )
102
+ {
103
+ get_pie_cb (skb )-> enqueue_time = psched_get_time ();
80
104
}
81
105
82
106
static void pie_vars_init (struct pie_vars * vars )
83
107
{
84
108
vars -> dq_count = DQCOUNT_INVALID ;
109
+ vars -> dq_tstamp = DTIME_INVALID ;
85
110
vars -> accu_prob = 0 ;
86
111
vars -> avg_dq_rate = 0 ;
87
112
/* default of 150 ms in pschedtime */
@@ -172,6 +197,10 @@ static int pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
172
197
173
198
/* we can enqueue the packet */
174
199
if (enqueue ) {
200
+ /* Set enqueue time only when dq_rate_estimator is disabled. */
201
+ if (!q -> params .dq_rate_estimator )
202
+ pie_set_enqueue_time (skb );
203
+
175
204
q -> stats .packets_in ++ ;
176
205
if (qdisc_qlen (sch ) > q -> stats .maxq )
177
206
q -> stats .maxq = qdisc_qlen (sch );
@@ -194,6 +223,7 @@ static const struct nla_policy pie_policy[TCA_PIE_MAX + 1] = {
194
223
[TCA_PIE_BETA ] = {.type = NLA_U32 },
195
224
[TCA_PIE_ECN ] = {.type = NLA_U32 },
196
225
[TCA_PIE_BYTEMODE ] = {.type = NLA_U32 },
226
+ [TCA_PIE_DQ_RATE_ESTIMATOR ] = {.type = NLA_U32 },
197
227
};
198
228
199
229
static int pie_change (struct Qdisc * sch , struct nlattr * opt ,
@@ -247,6 +277,10 @@ static int pie_change(struct Qdisc *sch, struct nlattr *opt,
247
277
if (tb [TCA_PIE_BYTEMODE ])
248
278
q -> params .bytemode = nla_get_u32 (tb [TCA_PIE_BYTEMODE ]);
249
279
280
+ if (tb [TCA_PIE_DQ_RATE_ESTIMATOR ])
281
+ q -> params .dq_rate_estimator =
282
+ nla_get_u32 (tb [TCA_PIE_DQ_RATE_ESTIMATOR ]);
283
+
250
284
/* Drop excess packets if new limit is lower */
251
285
qlen = sch -> q .qlen ;
252
286
while (sch -> q .qlen > sch -> limit ) {
@@ -266,6 +300,28 @@ static void pie_process_dequeue(struct Qdisc *sch, struct sk_buff *skb)
266
300
{
267
301
struct pie_sched_data * q = qdisc_priv (sch );
268
302
int qlen = sch -> qstats .backlog ; /* current queue size in bytes */
303
+ psched_time_t now = psched_get_time ();
304
+ u32 dtime = 0 ;
305
+
306
+ /* If dq_rate_estimator is disabled, calculate qdelay using the
307
+ * packet timestamp.
308
+ */
309
+ if (!q -> params .dq_rate_estimator ) {
310
+ q -> vars .qdelay = now - pie_get_enqueue_time (skb );
311
+
312
+ if (q -> vars .dq_tstamp != DTIME_INVALID )
313
+ dtime = now - q -> vars .dq_tstamp ;
314
+
315
+ q -> vars .dq_tstamp = now ;
316
+
317
+ if (qlen == 0 )
318
+ q -> vars .qdelay = 0 ;
319
+
320
+ if (dtime == 0 )
321
+ return ;
322
+
323
+ goto burst_allowance_reduction ;
324
+ }
269
325
270
326
/* If current queue is about 10 packets or more and dq_count is unset
271
327
* we have enough packets to calculate the drain rate. Save
@@ -289,10 +345,10 @@ static void pie_process_dequeue(struct Qdisc *sch, struct sk_buff *skb)
289
345
q -> vars .dq_count += skb -> len ;
290
346
291
347
if (q -> vars .dq_count >= QUEUE_THRESHOLD ) {
292
- psched_time_t now = psched_get_time ();
293
- u32 dtime = now - q -> vars .dq_tstamp ;
294
348
u32 count = q -> vars .dq_count << PIE_SCALE ;
295
349
350
+ dtime = now - q -> vars .dq_tstamp ;
351
+
296
352
if (dtime == 0 )
297
353
return ;
298
354
@@ -317,34 +373,45 @@ static void pie_process_dequeue(struct Qdisc *sch, struct sk_buff *skb)
317
373
q -> vars .dq_tstamp = psched_get_time ();
318
374
}
319
375
320
- if (q -> vars .burst_time > 0 ) {
321
- if (q -> vars .burst_time > dtime )
322
- q -> vars .burst_time -= dtime ;
323
- else
324
- q -> vars .burst_time = 0 ;
325
- }
376
+ goto burst_allowance_reduction ;
326
377
}
327
378
}
379
+
380
+ return ;
381
+
382
+ burst_allowance_reduction :
383
+ if (q -> vars .burst_time > 0 ) {
384
+ if (q -> vars .burst_time > dtime )
385
+ q -> vars .burst_time -= dtime ;
386
+ else
387
+ q -> vars .burst_time = 0 ;
388
+ }
328
389
}
329
390
330
391
static void calculate_probability (struct Qdisc * sch )
331
392
{
332
393
struct pie_sched_data * q = qdisc_priv (sch );
333
394
u32 qlen = sch -> qstats .backlog ; /* queue size in bytes */
334
395
psched_time_t qdelay = 0 ; /* in pschedtime */
335
- psched_time_t qdelay_old = q -> vars . qdelay ; /* in pschedtime */
396
+ psched_time_t qdelay_old = 0 ; /* in pschedtime */
336
397
s64 delta = 0 ; /* determines the change in probability */
337
398
u64 oldprob ;
338
399
u64 alpha , beta ;
339
400
u32 power ;
340
401
bool update_prob = true;
341
402
342
- q -> vars .qdelay_old = q -> vars .qdelay ;
403
+ if (q -> params .dq_rate_estimator ) {
404
+ qdelay_old = q -> vars .qdelay ;
405
+ q -> vars .qdelay_old = q -> vars .qdelay ;
343
406
344
- if (q -> vars .avg_dq_rate > 0 )
345
- qdelay = (qlen << PIE_SCALE ) / q -> vars .avg_dq_rate ;
346
- else
347
- qdelay = 0 ;
407
+ if (q -> vars .avg_dq_rate > 0 )
408
+ qdelay = (qlen << PIE_SCALE ) / q -> vars .avg_dq_rate ;
409
+ else
410
+ qdelay = 0 ;
411
+ } else {
412
+ qdelay = q -> vars .qdelay ;
413
+ qdelay_old = q -> vars .qdelay_old ;
414
+ }
348
415
349
416
/* If qdelay is zero and qlen is not, it means qlen is very small, less
350
417
* than dequeue_rate, so we do not update probabilty in this round
@@ -430,14 +497,18 @@ static void calculate_probability(struct Qdisc *sch)
430
497
/* We restart the measurement cycle if the following conditions are met
431
498
* 1. If the delay has been low for 2 consecutive Tupdate periods
432
499
* 2. Calculated drop probability is zero
433
- * 3. We have atleast one estimate for the avg_dq_rate ie.,
434
- * is a non-zero value
500
+ * 3. If average dq_rate_estimator is enabled, we have atleast one
501
+ * estimate for the avg_dq_rate ie., is a non-zero value
435
502
*/
436
503
if ((q -> vars .qdelay < q -> params .target / 2 ) &&
437
504
(q -> vars .qdelay_old < q -> params .target / 2 ) &&
438
505
q -> vars .prob == 0 &&
439
- q -> vars .avg_dq_rate > 0 )
506
+ (! q -> params . dq_rate_estimator || q -> vars .avg_dq_rate > 0 )) {
440
507
pie_vars_init (& q -> vars );
508
+ }
509
+
510
+ if (!q -> params .dq_rate_estimator )
511
+ q -> vars .qdelay_old = qdelay ;
441
512
}
442
513
443
514
static void pie_timer (struct timer_list * t )
@@ -497,7 +568,9 @@ static int pie_dump(struct Qdisc *sch, struct sk_buff *skb)
497
568
nla_put_u32 (skb , TCA_PIE_ALPHA , q -> params .alpha ) ||
498
569
nla_put_u32 (skb , TCA_PIE_BETA , q -> params .beta ) ||
499
570
nla_put_u32 (skb , TCA_PIE_ECN , q -> params .ecn ) ||
500
- nla_put_u32 (skb , TCA_PIE_BYTEMODE , q -> params .bytemode ))
571
+ nla_put_u32 (skb , TCA_PIE_BYTEMODE , q -> params .bytemode ) ||
572
+ nla_put_u32 (skb , TCA_PIE_DQ_RATE_ESTIMATOR ,
573
+ q -> params .dq_rate_estimator ))
501
574
goto nla_put_failure ;
502
575
503
576
return nla_nest_end (skb , opts );
@@ -514,16 +587,21 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
514
587
.prob = q -> vars .prob ,
515
588
.delay = ((u32 )PSCHED_TICKS2NS (q -> vars .qdelay )) /
516
589
NSEC_PER_USEC ,
517
- /* unscale and return dq_rate in bytes per sec */
518
- .avg_dq_rate = q -> vars .avg_dq_rate *
519
- (PSCHED_TICKS_PER_SEC ) >> PIE_SCALE ,
520
590
.packets_in = q -> stats .packets_in ,
521
591
.overlimit = q -> stats .overlimit ,
522
592
.maxq = q -> stats .maxq ,
523
593
.dropped = q -> stats .dropped ,
524
594
.ecn_mark = q -> stats .ecn_mark ,
525
595
};
526
596
597
+ /* avg_dq_rate is only valid if dq_rate_estimator is enabled */
598
+ st .dq_rate_estimating = q -> params .dq_rate_estimator ;
599
+
600
+ /* unscale and return dq_rate in bytes per sec */
601
+ if (q -> params .dq_rate_estimator )
602
+ st .avg_dq_rate = q -> vars .avg_dq_rate *
603
+ (PSCHED_TICKS_PER_SEC ) >> PIE_SCALE ;
604
+
527
605
return gnet_stats_copy_app (d , & st , sizeof (st ));
528
606
}
529
607
0 commit comments