@@ -100,6 +100,7 @@ struct fq_sched_data {
100
100
101
101
struct rb_root delayed ; /* for rate limited flows */
102
102
u64 time_next_delayed_flow ;
103
+ u64 ktime_cache ; /* copy of last ktime_get_ns() */
103
104
unsigned long unthrottle_latency_ns ;
104
105
105
106
struct fq_flow internal ; /* for non classified or high prio packets */
@@ -109,12 +110,13 @@ struct fq_sched_data {
109
110
u32 flow_plimit ; /* max packets per flow */
110
111
unsigned long flow_max_rate ; /* optional max rate per flow */
111
112
u64 ce_threshold ;
113
+ u64 horizon ; /* horizon in ns */
112
114
u32 orphan_mask ; /* mask for orphaned skb */
113
115
u32 low_rate_threshold ;
114
116
struct rb_root * fq_root ;
115
117
u8 rate_enable ;
116
118
u8 fq_trees_log ;
117
-
119
+ u8 horizon_drop ;
118
120
u32 flows ;
119
121
u32 inactive_flows ;
120
122
u32 throttled_flows ;
@@ -123,6 +125,8 @@ struct fq_sched_data {
123
125
u64 stat_internal_packets ;
124
126
u64 stat_throttled ;
125
127
u64 stat_ce_mark ;
128
+ u64 stat_horizon_drops ;
129
+ u64 stat_horizon_caps ;
126
130
u64 stat_flows_plimit ;
127
131
u64 stat_pkts_too_long ;
128
132
u64 stat_allocation_errors ;
@@ -402,8 +406,6 @@ static void flow_queue_add(struct fq_flow *flow, struct sk_buff *skb)
402
406
struct rb_node * * p , * parent ;
403
407
struct sk_buff * head , * aux ;
404
408
405
- fq_skb_cb (skb )-> time_to_send = skb -> tstamp ?: ktime_get_ns ();
406
-
407
409
head = flow -> head ;
408
410
if (!head ||
409
411
fq_skb_cb (skb )-> time_to_send >= fq_skb_cb (flow -> tail )-> time_to_send ) {
@@ -431,6 +433,12 @@ static void flow_queue_add(struct fq_flow *flow, struct sk_buff *skb)
431
433
rb_insert_color (& skb -> rbnode , & flow -> t_root );
432
434
}
433
435
436
+ static bool fq_packet_beyond_horizon (const struct sk_buff * skb ,
437
+ const struct fq_sched_data * q )
438
+ {
439
+ return unlikely ((s64 )skb -> tstamp > (s64 )(q -> ktime_cache + q -> horizon ));
440
+ }
441
+
434
442
static int fq_enqueue (struct sk_buff * skb , struct Qdisc * sch ,
435
443
struct sk_buff * * to_free )
436
444
{
@@ -440,6 +448,28 @@ static int fq_enqueue(struct sk_buff *skb, struct Qdisc *sch,
440
448
if (unlikely (sch -> q .qlen >= sch -> limit ))
441
449
return qdisc_drop (skb , sch , to_free );
442
450
451
+ if (!skb -> tstamp ) {
452
+ fq_skb_cb (skb )-> time_to_send = q -> ktime_cache = ktime_get_ns ();
453
+ } else {
454
+ /* Check if packet timestamp is too far in the future.
455
+ * Try first if our cached value, to avoid ktime_get_ns()
456
+ * cost in most cases.
457
+ */
458
+ if (fq_packet_beyond_horizon (skb , q )) {
459
+ /* Refresh our cache and check another time */
460
+ q -> ktime_cache = ktime_get_ns ();
461
+ if (fq_packet_beyond_horizon (skb , q )) {
462
+ if (q -> horizon_drop ) {
463
+ q -> stat_horizon_drops ++ ;
464
+ return qdisc_drop (skb , sch , to_free );
465
+ }
466
+ q -> stat_horizon_caps ++ ;
467
+ skb -> tstamp = q -> ktime_cache + q -> horizon ;
468
+ }
469
+ }
470
+ fq_skb_cb (skb )-> time_to_send = skb -> tstamp ;
471
+ }
472
+
443
473
f = fq_classify (skb , q );
444
474
if (unlikely (f -> qlen >= q -> flow_plimit && f != & q -> internal )) {
445
475
q -> stat_flows_plimit ++ ;
@@ -512,7 +542,7 @@ static struct sk_buff *fq_dequeue(struct Qdisc *sch)
512
542
goto out ;
513
543
}
514
544
515
- now = ktime_get_ns ();
545
+ q -> ktime_cache = now = ktime_get_ns ();
516
546
fq_check_throttled (q , now );
517
547
begin :
518
548
head = & q -> new_flows ;
@@ -765,6 +795,8 @@ static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = {
765
795
[TCA_FQ_LOW_RATE_THRESHOLD ] = { .type = NLA_U32 },
766
796
[TCA_FQ_CE_THRESHOLD ] = { .type = NLA_U32 },
767
797
[TCA_FQ_TIMER_SLACK ] = { .type = NLA_U32 },
798
+ [TCA_FQ_HORIZON ] = { .type = NLA_U32 },
799
+ [TCA_FQ_HORIZON_DROP ] = { .type = NLA_U8 },
768
800
};
769
801
770
802
static int fq_change (struct Qdisc * sch , struct nlattr * opt ,
@@ -854,7 +886,15 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt,
854
886
if (tb [TCA_FQ_TIMER_SLACK ])
855
887
q -> timer_slack = nla_get_u32 (tb [TCA_FQ_TIMER_SLACK ]);
856
888
889
+ if (tb [TCA_FQ_HORIZON ])
890
+ q -> horizon = (u64 )NSEC_PER_USEC *
891
+ nla_get_u32 (tb [TCA_FQ_HORIZON ]);
892
+
893
+ if (tb [TCA_FQ_HORIZON_DROP ])
894
+ q -> horizon_drop = nla_get_u8 (tb [TCA_FQ_HORIZON_DROP ]);
895
+
857
896
if (!err ) {
897
+
858
898
sch_tree_unlock (sch );
859
899
err = fq_resize (sch , fq_log );
860
900
sch_tree_lock (sch );
@@ -907,6 +947,9 @@ static int fq_init(struct Qdisc *sch, struct nlattr *opt,
907
947
908
948
q -> timer_slack = 10 * NSEC_PER_USEC ; /* 10 usec of hrtimer slack */
909
949
950
+ q -> horizon = 10ULL * NSEC_PER_SEC ; /* 10 seconds */
951
+ q -> horizon_drop = 1 ; /* by default, drop packets beyond horizon */
952
+
910
953
/* Default ce_threshold of 4294 seconds */
911
954
q -> ce_threshold = (u64 )NSEC_PER_USEC * ~0U ;
912
955
@@ -924,6 +967,7 @@ static int fq_dump(struct Qdisc *sch, struct sk_buff *skb)
924
967
{
925
968
struct fq_sched_data * q = qdisc_priv (sch );
926
969
u64 ce_threshold = q -> ce_threshold ;
970
+ u64 horizon = q -> horizon ;
927
971
struct nlattr * opts ;
928
972
929
973
opts = nla_nest_start_noflag (skb , TCA_OPTIONS );
@@ -933,6 +977,7 @@ static int fq_dump(struct Qdisc *sch, struct sk_buff *skb)
933
977
/* TCA_FQ_FLOW_DEFAULT_RATE is not used anymore */
934
978
935
979
do_div (ce_threshold , NSEC_PER_USEC );
980
+ do_div (horizon , NSEC_PER_USEC );
936
981
937
982
if (nla_put_u32 (skb , TCA_FQ_PLIMIT , sch -> limit ) ||
938
983
nla_put_u32 (skb , TCA_FQ_FLOW_PLIMIT , q -> flow_plimit ) ||
@@ -948,7 +993,9 @@ static int fq_dump(struct Qdisc *sch, struct sk_buff *skb)
948
993
q -> low_rate_threshold ) ||
949
994
nla_put_u32 (skb , TCA_FQ_CE_THRESHOLD , (u32 )ce_threshold ) ||
950
995
nla_put_u32 (skb , TCA_FQ_BUCKETS_LOG , q -> fq_trees_log ) ||
951
- nla_put_u32 (skb , TCA_FQ_TIMER_SLACK , q -> timer_slack ))
996
+ nla_put_u32 (skb , TCA_FQ_TIMER_SLACK , q -> timer_slack ) ||
997
+ nla_put_u32 (skb , TCA_FQ_HORIZON , (u32 )horizon ) ||
998
+ nla_put_u8 (skb , TCA_FQ_HORIZON_DROP , q -> horizon_drop ))
952
999
goto nla_put_failure ;
953
1000
954
1001
return nla_nest_end (skb , opts );
@@ -979,6 +1026,8 @@ static int fq_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
979
1026
st .unthrottle_latency_ns = min_t (unsigned long ,
980
1027
q -> unthrottle_latency_ns , ~0U );
981
1028
st .ce_mark = q -> stat_ce_mark ;
1029
+ st .horizon_drops = q -> stat_horizon_drops ;
1030
+ st .horizon_caps = q -> stat_horizon_caps ;
982
1031
sch_tree_unlock (sch );
983
1032
984
1033
return gnet_stats_copy_app (d , & st , sizeof (st ));
0 commit comments