diff --git a/pkt_sched.h b/pkt_sched.h index 0bacd6e..4c2e7a2 100644 --- a/pkt_sched.h +++ b/pkt_sched.h @@ -852,6 +852,19 @@ struct tc_pie_xstats { }; /* CAKE */ + +struct tc_cake_cl_stats { + __s32 deficit; + __u32 count; + __u32 dropping; + __s32 drop_next; +}; + +enum { + TCA_CAKE_XSTATS_QDISC, + TCA_CAKE_XSTATS_CLASS, +}; + enum { TCA_CAKE_UNSPEC, TCA_CAKE_BASE_RATE, diff --git a/sch_cake.c b/sch_cake.c index a3244f1..a21be68 100644 --- a/sch_cake.c +++ b/sch_cake.c @@ -124,7 +124,7 @@ struct cake_bin_data { u32 flows_cnt; /* number of flows - must be multiple of * CAKE_SET_WAYS */ - u32 perturbation;/* hash perturbation */ + u32 perturbation; /* hash perturbation */ u16 quantum; /* psched_mtu(qdisc_dev(sch)); */ struct codel_params cparams; @@ -176,10 +176,10 @@ struct cake_sched_data { u16 rate_shft; u64 time_next_packet; u32 rate_ns; - u16 peel_threshold; u32 rate_bps; u16 rate_flags; - short rate_overhead; + u16 peel_threshold; + u16 rate_overhead; /* resource tracking */ u32 buffer_used; @@ -191,14 +191,15 @@ struct cake_sched_data { struct qdisc_watchdog watchdog; u8 bin_index[64]; + u32 interval; }; enum { - CAKE_MODE_BESTEFFORT = 1, + CAKE_MODE_SQUASH, + CAKE_MODE_BESTEFFORT, CAKE_MODE_PRECEDENCE, CAKE_MODE_DIFFSERV8, CAKE_MODE_DIFFSERV4, - CAKE_MODE_SQUASH, CAKE_MODE_MAX }; @@ -297,11 +298,10 @@ cake_hash(struct cake_bin_data *q, const struct sk_buff *skb, int flow_mode) } host_hash = flow_hash_from_keys(&host_keys); - if (!(flow_mode & CAKE_FLOW_FLOWS)) { + if (!(flow_mode & CAKE_FLOW_FLOWS)) flow_hash = host_hash; - } else { + else flow_hash = flow_hash_from_keys(&keys); - } #endif reduced_hash = reciprocal_scale(flow_hash, q->flows_cnt); @@ -781,6 +781,8 @@ static const struct nla_policy cake_policy[TCA_CAKE_MAX + 1] = { [TCA_CAKE_ATM] = { .type = NLA_U32 }, [TCA_CAKE_FLOW_MODE] = { .type = NLA_U32 }, [TCA_CAKE_OVERHEAD] = { .type = NLA_U32 }, + [TCA_CAKE_ACTIVE_FLOWS] = { .type = NLA_U32 }, + [TCA_CAKE_RTT] = { .type = NLA_U32 }, }; static void cake_set_rate(struct cake_bin_data *b, u64 rate, u32 mtu, @@ -834,7 +836,7 @@ static void cake_config_besteffort(struct Qdisc *sch) for (i = 0; i < 64; i++) q->bin_index[i] = 0; - cake_set_rate(b, rate, mtu, MS2TIME(5), MS2TIME(100)); + cake_set_rate(b, rate, mtu, MS2TIME(5), q->interval); b->bin_quantum_band = 65535; b->bin_quantum_prio = 65535; } @@ -857,7 +859,7 @@ static void cake_config_precedence(struct Qdisc *sch) for (i = 0; i < q->bin_cnt; i++) { struct cake_bin_data *b = &q->bins[i]; - cake_set_rate(b, rate, mtu, MS2TIME(5), MS2TIME(100)); + cake_set_rate(b, rate, mtu, MS2TIME(5), q->interval); b->bin_quantum_prio = max_t(u16, 1U, quantum1); b->bin_quantum_band = max_t(u16, 1U, quantum2); @@ -970,7 +972,7 @@ static void cake_config_diffserv8(struct Qdisc *sch) for (i = 0; i < q->bin_cnt; i++) { struct cake_bin_data *b = &q->bins[i]; - cake_set_rate(b, rate, mtu, MS2TIME(5), MS2TIME(100)); + cake_set_rate(b, rate, mtu, MS2TIME(5), q->interval); b->bin_quantum_prio = max_t(u16, 1U, quantum1); b->bin_quantum_band = max_t(u16, 1U, quantum2); @@ -1032,13 +1034,13 @@ static void cake_config_diffserv4(struct Qdisc *sch) } /* class characteristics */ - cake_set_rate(&q->bins[0], rate, mtu, MS2TIME(5), MS2TIME(100)); + cake_set_rate(&q->bins[0], rate, mtu, MS2TIME(5), q->interval); cake_set_rate(&q->bins[1], rate - (rate >> 4), mtu, MS2TIME(5), - MS2TIME(100)); + q->interval); cake_set_rate(&q->bins[2], rate - (rate >> 2), mtu, MS2TIME(5), - MS2TIME(100)); + q->interval); cake_set_rate(&q->bins[3], rate >> 2, mtu, MS2TIME(5), - MS2TIME(100)); + q->interval); /* priority weights */ q->bins[0].bin_quantum_prio = quantum >> 4; @@ -1136,6 +1138,9 @@ static int cake_change(struct Qdisc *sch, struct nlattr *opt) if (tb[TCA_CAKE_OVERHEAD]) q->rate_overhead = nla_get_u32(tb[TCA_CAKE_OVERHEAD]); + if (tb[TCA_CAKE_RTT]) + q->interval = NSEC_PER_USEC * nla_get_u32(tb[TCA_CAKE_RTT]); + if (q->bins) { sch_tree_lock(sch); cake_reconfigure(sch); @@ -1271,6 +1276,9 @@ static int cake_dump(struct Qdisc *sch, struct sk_buff *skb) if (nla_put_u32(skb, TCA_CAKE_OVERHEAD, q->rate_overhead)) goto nla_put_failure; + if (nla_put_u32(skb, TCA_CAKE_RTT, codel_time_to_us(q->interval))) + goto nla_put_failure; + return nla_nest_end(skb, opts); nla_put_failure: @@ -1359,12 +1367,11 @@ static int cake_dump_bin(struct Qdisc *sch, unsigned long cl, static int cake_dump_class_stats(struct Qdisc *sch, unsigned long cl, struct gnet_dump *d) { - /* reuse fq_codel stats format */ struct cake_sched_data *q = qdisc_priv(sch); struct cake_bin_data *b = q->bins; u32 bin = 0, idx = cl - 1; struct gnet_stats_queue qs = {0}; - struct tc_fq_codel_xstats xstats; + struct tc_cake_cl_stats xstats; while (bin < q->bin_cnt && idx >= b->flows_cnt) { idx -= b->flows_cnt; @@ -1377,11 +1384,9 @@ static int cake_dump_class_stats(struct Qdisc *sch, unsigned long cl, const struct sk_buff *skb = flow->head; memset(&xstats, 0, sizeof(xstats)); - xstats.type = TCA_FQ_CODEL_XSTATS_CLASS; + xstats.type = TCA_CAKE_XSTATS_CLASS; xstats.class_stats.deficit = flow->deficit; - xstats.class_stats.ldelay = 0; xstats.class_stats.count = flow->cvars.count; - xstats.class_stats.lastcount = 0; xstats.class_stats.dropping = flow->cvars.dropping; if (flow->cvars.dropping) { codel_tdiff_t delta = flow->cvars.drop_next -