iproute2: tc: fq_codel: add per queue memory limit

This commit is contained in:
Linus Lüssing 2018-01-17 19:03:22 +01:00
parent e349c3b0cc
commit 2bbf79de29

View File

@ -0,0 +1,129 @@
From: Linus Lüssing <linus.luessing@c0d3.blue>
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 <eric.dumazet@gmail.com>
+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 <edumazet@google.com>
+---
+ 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
+