From: Linus Lüssing Date: Thu, 4 Jan 2018 01:55:00 +0100 Subject: iproute2: tc: fq_codel: add per queue memory limit This allows monitoring the fq-codel memory limit related statistics from userspace via tc. diff --git a/package/network/utils/iproute2/patches/140-fq_codel-add-per-queue-memory-limit.patch b/package/network/utils/iproute2/patches/140-fq_codel-add-per-queue-memory-limit.patch new file mode 100644 index 0000000000000000000000000000000000000000..02c7d9fba04b5cf8dc0a9904bec81e9510527a63 --- /dev/null +++ b/package/network/utils/iproute2/patches/140-fq_codel-add-per-queue-memory-limit.patch @@ -0,0 +1,116 @@ +From bc5584d7ba7bc3cd9104e179450e478fde263b27 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 8 Jun 2016 08:42:00 -0700 +Subject: [PATCH] fq_codel: add per queue memory limit + +This patch adds support for TCA_FQ_CODEL_MEMORY_LIMIT attribute. + +.. +qdisc fq_codel 8008: root refcnt 257 limit 10240p flows 1024 + quantum 1514 target 5.0ms interval 100.0ms memory_limit 4Mb ecn + Sent 2083566791363 bytes 1376214889 pkt (dropped 4994406, overlimits 0 +requeues 21705223) + rate 9841Mbit 812549pps backlog 3906120b 376p requeues 21705223 + maxpacket 68130 drop_overlimit 4994406 new_flow_count 28855414 + ecn_mark 0 memory_used 4190048 drop_overmemory 4994406 +new_flows_len 1 old_flows_len 177 + +Signed-off-by: Eric Dumazet +--- + include/linux/pkt_sched.h | 4 ++++ + tc/q_fq_codel.c | 22 ++++++++++++++++++++++ + 2 files changed, 26 insertions(+) + +diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h +index 8d2530da..112cca43 100644 +--- a/include/linux/pkt_sched.h ++++ b/include/linux/pkt_sched.h +@@ -711,6 +711,8 @@ enum { + TCA_FQ_CODEL_FLOWS, + TCA_FQ_CODEL_QUANTUM, + TCA_FQ_CODEL_CE_THRESHOLD, ++ TCA_FQ_CODEL_DROP_BATCH_SIZE, ++ TCA_FQ_CODEL_MEMORY_LIMIT, + __TCA_FQ_CODEL_MAX + }; + +@@ -735,6 +737,8 @@ struct tc_fq_codel_qd_stats { + __u32 new_flows_len; /* count of flows in new list */ + __u32 old_flows_len; /* count of flows in old list */ + __u32 ce_mark; /* packets above ce_threshold */ ++ __u32 memory_usage; /* in bytes */ ++ __u32 drop_overmemory; + }; + + struct tc_fq_codel_cl_stats { +diff --git a/tc/q_fq_codel.c b/tc/q_fq_codel.c +index 4f747ebd..add3899c 100644 +--- a/tc/q_fq_codel.c ++++ b/tc/q_fq_codel.c +@@ -65,6 +65,7 @@ static int fq_codel_parse_opt(struct qdisc_util *qu, int argc, char **argv, + unsigned interval = 0; + unsigned quantum = 0; + unsigned ce_threshold = ~0U; ++ unsigned memory = ~0U; + int ecn = -1; + struct rtattr *tail; + +@@ -99,6 +100,12 @@ static int fq_codel_parse_opt(struct qdisc_util *qu, int argc, char **argv, + fprintf(stderr, "Illegal \"ce_threshold\"\n"); + return -1; + } ++ } else if (strcmp(*argv, "memory_limit") == 0) { ++ NEXT_ARG(); ++ if (get_size(&memory, *argv)) { ++ fprintf(stderr, "Illegal \"memory_limit\"\n"); ++ return -1; ++ } + } else if (strcmp(*argv, "interval") == 0) { + NEXT_ARG(); + if (get_time(&interval, *argv)) { +@@ -137,6 +144,10 @@ static int fq_codel_parse_opt(struct qdisc_util *qu, int argc, char **argv, + if (ce_threshold != ~0U) + addattr_l(n, 1024, TCA_FQ_CODEL_CE_THRESHOLD, + &ce_threshold, sizeof(ce_threshold)); ++ if (memory != ~0U) ++ addattr_l(n, 1024, TCA_FQ_CODEL_MEMORY_LIMIT, ++ &memory, sizeof(memory)); ++ + tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; + return 0; + } +@@ -151,6 +162,7 @@ static int fq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt + unsigned ecn; + unsigned quantum; + unsigned ce_threshold; ++ unsigned int memory_limit; + SPRINT_BUF(b1); + + if (opt == NULL) +@@ -188,6 +200,12 @@ static int fq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt + interval = rta_getattr_u32(tb[TCA_FQ_CODEL_INTERVAL]); + fprintf(f, "interval %s ", sprint_time(interval, b1)); + } ++ if (tb[TCA_FQ_CODEL_MEMORY_LIMIT] && ++ RTA_PAYLOAD(tb[TCA_FQ_CODEL_MEMORY_LIMIT]) >= sizeof(__u32)) { ++ memory_limit = rta_getattr_u32(tb[TCA_FQ_CODEL_MEMORY_LIMIT]); ++ ++ fprintf(f, "memory_limit %s ", sprint_size(memory_limit, b1)); ++ } + if (tb[TCA_FQ_CODEL_ECN] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_ECN]) >= sizeof(__u32)) { + ecn = rta_getattr_u32(tb[TCA_FQ_CODEL_ECN]); +@@ -221,6 +239,10 @@ static int fq_codel_print_xstats(struct qdisc_util *qu, FILE *f, + st->qdisc_stats.ecn_mark); + if (st->qdisc_stats.ce_mark) + fprintf(f, " ce_mark %u", st->qdisc_stats.ce_mark); ++ if (st->qdisc_stats.memory_usage) ++ fprintf(f, " memory_used %u", st->qdisc_stats.memory_usage); ++ if (st->qdisc_stats.drop_overmemory) ++ fprintf(f, " drop_overmemory %u", st->qdisc_stats.drop_overmemory); + fprintf(f, "\n new_flows_len %u old_flows_len %u", + st->qdisc_stats.new_flows_len, + st->qdisc_stats.old_flows_len); +-- +2.11.0 +