From nobody Mon Jun 8 07:23:59 2026 Received: from mail-pg1-f170.google.com (mail-pg1-f170.google.com [209.85.215.170]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 07734344DB9 for ; Sun, 31 May 2026 13:14:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780233289; cv=none; b=tkgbgwyT5G8dOEKYStjUMW/TMSlCNNLpYViJ/NzeqwdCHupUmqsRuP0C9AbDwcEwCam2qAO23fcsKqliBQjz+P4DVJHNg180hqAUVvdh/neXeK1PyPh8wOOn92ZOfqGvuop/eA4ZWSnxPTqpU0YzEq7SN76IJemeEtysxO0jlr8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780233289; c=relaxed/simple; bh=0aShnTLAhiuyEB5pyT5AYtZfG/JhG9Yw7MCMWNgnOG0=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=aAvptZzhu79oZbV4R5F06SP8+FICA6LAFdSJerb8w9KucvKurlUqqQ02//LqewFTSK4c8iNyUK5NM0SY3U4YHMiY6gHReDXJpmhC8rO0Bg6yLkvHv3YIff0doaLf4FL+w3In9UszW5RO4cGXFGsrNlU8IMqAPJ+r4ASf2ZUOTDk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=o2JmH5WY; arc=none smtp.client-ip=209.85.215.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="o2JmH5WY" Received: by mail-pg1-f170.google.com with SMTP id 41be03b00d2f7-c857fba35cfso623384a12.1 for ; Sun, 31 May 2026 06:14:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1780233287; x=1780838087; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=LDSYzXlHDg7TAcmv0nXLDs8v9+ggmKHkwJHTwxsSA0U=; b=o2JmH5WYxhNf/hoJEmRoM9yQWAOkFTqq66Dl5s0Kt3/8ZOeUdp6c/6sxsysHLMQE1X GrAkcqBSAoFK2IC6ufePhNbueEg+Y8aoWyrY0d05xOb6i9XaOoz4ZXyNewTCoiKDpaNT q5aMUTw+8mVJbhSeaO23WqKhle5JONbYPg/q6KfGfnuUNPy+Vb4okQeafbKQMj1H8woE NkdCpA6fj+2zbzDcYHoRXOqcV+yQHwf6fNnhAGwkGyv842U0oqobO5mePrt3hE6arAem +PyTioKrdFSb9vNSV2MmPOsF1OryADl+55xBgfMk1pwRP8E/wD+rIsnCLLZhIy0oxyZx qkcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780233287; x=1780838087; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=LDSYzXlHDg7TAcmv0nXLDs8v9+ggmKHkwJHTwxsSA0U=; b=E4JUnSkXdwNnl/TAi5cCv35zWCUW6Y1qT2WI3tPLS0/qI8Y6VIk9rs9t9tG0wKB9KD ZXEuevHeEt7z19ZgCCrGFrqwPtX9UcQXOwkJJZubOy9hhATADAYBTnVIXo6NMNlHW1iT WoIzEszcClX43qXZ0r8w+ybIhgE9FzVBuO7Gvow+MXhm8bXesLcreKJg4J2mpE4VTt0O SsqblkkRk/x08c/dALx3+OAiWzEkNmibmNy40U0QIcDuZUbR50k4q2YWCzLK2DuO6H/P phm/mhqPawdiKGaLYGd/3brquHL5JZ8D7MiGauI8cD3I5dJfaSV5Jam5B1Gqb+nec9qC 8lqQ== X-Forwarded-Encrypted: i=1; AFNElJ+hwc7H2jkK8ftCTeCyvjIqWGbgVU2RWYwO01xaUJyaU5aQ69pRQd8d74bnuvdHzmbE5rQwofBeukMrrVc=@vger.kernel.org X-Gm-Message-State: AOJu0YzwRV9I4SVhFn7RREq4A5xtiudbTJuQWTA9qL5ZeRcngXXlUEIJ qIMNxW5dpnW4QEqPCkIjP4bxC72t4YZ278PQY6F6BNHfLDn4hv0Xk1Vk X-Gm-Gg: Acq92OG8JGVL00vKLPUI/PiTsAfvqU61SDN90FuzSA/e9VM2aX0kxmQ92Uo0/eejBpe by14Ix8xNWhL36ojcreIFGJtb7zL7DyF6mEfpqR+hJe319jYQ+tB+8CHqNFPSiegCjrSDjHUD+0 FvdbP+3ckRiZ4SBftPaJ43R6qkTjs9enORMeiIxfLWzPMVPudo7PW67IYd/GXbeHzdxJLKBRxq1 O46+P6aQ3d/WNBC3vZnOUptc0Csu0oxRdZidBjAxs2Do3idT6+uWM7ZqxWbO3K/FkpXb589CqIk HJchKaFViyX1bYyVsHALv+H+T+IuwP7jWDjAPQvCNu7EMiXF9jjFAASLstc4b/axfZpvSi7prlV LqdmQnkMRgd6AnC5oOQf/OhVOEv65EBr/QkMxTIL8aBFDiL9jC3h2Fmqx30rzpc0+4zaufK/qrf Uo2xxM5qpLFqN+SPw1xX9fUS8pUK5qnL1ylKZkb4XdiWSDTtTt7w== X-Received: by 2002:a05:6a20:1c8f:b0:39b:8dcb:f37d with SMTP id adf61e73a8af0-3b427eb0f6cmr7039190637.17.1780233286923; Sun, 31 May 2026 06:14:46 -0700 (PDT) Received: from Inspiron-14-5420.. ([2402:e280:21c6:671:7f12:602a:a4c6:2b38]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-c859391cbfbsm3442107a12.17.2026.05.31.06.14.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 31 May 2026 06:14:46 -0700 (PDT) From: "Hemendra M. Naik" To: netdev@vger.kernel.org Cc: jiri@resnulli.us, jhs@mojatatu.com, linux-kernel@vger.kernel.org, vishy0777@gmail.com, tahiliani@nitk.edu.in, "Hemendra M. Naik" Subject: [PATCH iproute2-next] tc: display per-flow class statistics for fq_pie Date: Sun, 31 May 2026 18:44:11 +0530 Message-Id: <20260531131411.28213-1-hemendranaik@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for printing per-flow PIE statistics exposed by the kernel via the new TCA_FQ_PIE_XSTATS_CLASS type in tc_fq_pie_xstats. 'tc -s class show' against an fq_pie qdisc now prints: prob drop probability for the flow delay per-flow queue sojourn time (microseconds) deficit remaining DRR byte credits (signed integer) avg_dq_rate dequeue rate estimate in bytes/second (dq_rate_estimator mode only) avg_dq_rate is formatted using tc_print_rate(), which converts the kernel's bytes/second value to a human-readable bits/second string (e.g. '3906Kbit'), consistent with how other tc schedulers display rate fields. Apply the same fix to tc/q_pie.c, where avg_dq_rate was also printed as a raw integer without a unit. Update the UAPI header to mirror tc_fq_pie_cl_stats from the kernel. Fix the 'delay' field comment in struct tc_pie_xstats from "in ms" to "in microseconds" to match the kernel's PSCHED_TICKS2NS / NSEC_PER_USEC conversion. Add a 'tc -s class show' example to tc-fq_pie(8) with dq_rate_estimator enabled, showing all per-flow fields (prob, delay, deficit, avg_dq_rate) across multiple flows. Update tc-pie(8) avg_dq_rate example from a raw integer to a formatted bits/second string. The corresponding kernel patch can bew viewed:=20 https://lore.kernel.org/netdev/20260531125314.22492-1-hemendranaik@gmail.co= m/ Signed-off-by: Hemendra M. Naik Signed-off-by: Vishal Kamath Signed-off-by: Mohit P. Tahiliani --- include/uapi/linux/pkt_sched.h | 29 +++++++++++++++-- man/man8/tc-fq_pie.8 | 19 ++++++++++++ man/man8/tc-pie.8 | 2 +- tc/q_fq_pie.c | 57 +++++++++++++++++++++++----------- tc/q_pie.c | 4 +-- 5 files changed, 87 insertions(+), 24 deletions(-) diff --git a/include/uapi/linux/pkt_sched.h b/include/uapi/linux/pkt_sched.h index fb07a889..9cc040b1 100644 --- a/include/uapi/linux/pkt_sched.h +++ b/include/uapi/linux/pkt_sched.h @@ -910,9 +910,9 @@ enum { =20 struct tc_pie_xstats { __u64 prob; /* current probability */ - __u32 delay; /* current delay in ms */ + __u32 delay; /* current delay in microseconds */ __u32 avg_dq_rate; /* current average dq_rate in - * bits/pie_time + * bytes/second */ __u32 dq_rate_estimating; /* is avg_dq_rate being calculated? */ __u32 packets_in; /* total number of packets enqueued */ @@ -943,7 +943,12 @@ enum { }; #define TCA_FQ_PIE_MAX (__TCA_FQ_PIE_MAX - 1) =20 -struct tc_fq_pie_xstats { +enum { + TCA_FQ_PIE_XSTATS_QDISC, + TCA_FQ_PIE_XSTATS_CLASS, +}; + +struct tc_fq_pie_qd_stats { __u32 packets_in; /* total number of packets enqueued */ __u32 dropped; /* packets dropped due to fq_pie_action */ __u32 overlimit; /* dropped due to lack of space in queue */ @@ -955,6 +960,24 @@ struct tc_fq_pie_xstats { __u32 memory_usage; /* total memory across all queues */ }; =20 +struct tc_fq_pie_cl_stats { + __u64 prob; /* current probability */ + __u32 delay; /* current delay in microseconds */ + __s32 deficit; /* number of remaining byte credits */ + __u32 avg_dq_rate; /* current average dq_rate in + * bytes/second + */ + __u32 dq_rate_estimating; /* is avg_dq_rate being calculated? */ +}; + +struct tc_fq_pie_xstats { + __u32 type; + union { + struct tc_fq_pie_qd_stats qdisc_stats; + struct tc_fq_pie_cl_stats class_stats; + }; +}; + /* CBS */ struct tc_cbs_qopt { __u8 offload; diff --git a/man/man8/tc-fq_pie.8 b/man/man8/tc-fq_pie.8 index 457a56bb..1c8ca1a6 100644 --- a/man/man8/tc-fq_pie.8 +++ b/man/man8/tc-fq_pie.8 @@ -153,6 +153,25 @@ dq_rate_estimator pkts_in 6082 overlimit 0 overmemory 0 dropped 4 ecn_mark 0 new_flow_count 94 new_flows_len 0 old_flows_len 8 memory_used 1157632 =20 +# tc qdisc add dev eth0 parent 100:1 handle 200: fq_pie target 15ms flows = 3 dq_rate_estimator +.br +# tc -s class show dev eth0 +.br +class fq_pie 200:1 parent 200: + (dropped 0, overlimits 0 requeues 0) + backlog 0b 0p requeues 0 + prob 0.000000 delay 0us deficit 1514 avg_dq_rate 0bit +.br +class fq_pie 200:2 parent 200: + (dropped 0, overlimits 0 requeues 0) + backlog 0b 0p requeues 0 + prob 0.000000 delay 0us deficit 1514 avg_dq_rate 0bit +.br +class fq_pie 200:3 parent 200: + (dropped 0, overlimits 0 requeues 0) + backlog 4470b 3p requeues 0 + prob 0.509691 delay 6.1ms deficit -82 avg_dq_rate 3906Kbit + .SH SEE ALSO .BR tc (8), .BR tc-pie (8), diff --git a/man/man8/tc-pie.8 b/man/man8/tc-pie.8 index 5a8c7820..ec0d4af2 100644 --- a/man/man8/tc-pie.8 +++ b/man/man8/tc-pie.8 @@ -115,7 +115,7 @@ is turned off. qdisc pie 8036: dev eth0 root refcnt 2 limit 1000p target 15.0ms tupdat= e 16.0ms alpha 2 beta 20 Sent 63947420 bytes 42414 pkt (dropped 41, overlimits 0 requeues 0) backlog 271006b 179p requeues 0 - prob 0.000092 delay 22200us avg_dq_rate 12145996 + prob 0.000092 delay 22200us avg_dq_rate 10742Kbit pkts_in 41 overlimit 343 dropped 0 maxq 50 ecn_mark 0 =20 # tc qdisc add dev eth0 root pie limit 100 target 20ms tupdate 30ms ecn diff --git a/tc/q_fq_pie.c b/tc/q_fq_pie.c index dc2710cd..80b956e8 100644 --- a/tc/q_fq_pie.c +++ b/tc/q_fq_pie.c @@ -274,6 +274,8 @@ static int fq_pie_print_xstats(const struct qdisc_util = *qu, FILE *f, { struct tc_fq_pie_xstats _st =3D {}, *st; =20 + SPRINT_BUF(b1); + if (xstats =3D=3D NULL) return 0; =20 @@ -283,25 +285,44 @@ static int fq_pie_print_xstats(const struct qdisc_uti= l *qu, FILE *f, st =3D &_st; } =20 - print_uint(PRINT_ANY, "pkts_in", " pkts_in %u", - st->packets_in); - print_uint(PRINT_ANY, "overlimit", " overlimit %u", - st->overlimit); - print_uint(PRINT_ANY, "overmemory", " overmemory %u", - st->overmemory); - print_uint(PRINT_ANY, "dropped", " dropped %u", - st->dropped); - print_uint(PRINT_ANY, "ecn_mark", " ecn_mark %u", - st->ecn_mark); + if (st->type =3D=3D TCA_FQ_PIE_XSTATS_QDISC) { + print_uint(PRINT_ANY, "pkts_in", " pkts_in %u", + st->qdisc_stats.packets_in); + print_uint(PRINT_ANY, "overlimit", " overlimit %u", + st->qdisc_stats.overlimit); + print_uint(PRINT_ANY, "overmemory", " overmemory %u", + st->qdisc_stats.overmemory); + print_uint(PRINT_ANY, "dropped", " dropped %u", + st->qdisc_stats.dropped); + print_uint(PRINT_ANY, "ecn_mark", " ecn_mark %u", + st->qdisc_stats.ecn_mark); + print_nl(); + print_uint(PRINT_ANY, "new_flow_count", " new_flow_count %u", + st->qdisc_stats.new_flow_count); + print_uint(PRINT_ANY, "new_flows_len", " new_flows_len %u", + st->qdisc_stats.new_flows_len); + print_uint(PRINT_ANY, "old_flows_len", " old_flows_len %u", + st->qdisc_stats.old_flows_len); + print_uint(PRINT_ANY, "memory_used", " memory_used %u", + st->qdisc_stats.memory_usage); + } + + if (st->type =3D=3D TCA_FQ_PIE_XSTATS_CLASS) { + print_float(PRINT_ANY, "prob", " prob %lg", + (double)st->class_stats.prob / (double)UINT64_MAX); + print_uint(PRINT_JSON, "delay", NULL, st->class_stats.delay); + print_string(PRINT_FP, NULL, " delay %s", + sprint_time(st->class_stats.delay, b1)); + print_int(PRINT_ANY, "deficit", " deficit %d", + st->class_stats.deficit); + + if (st->class_stats.dq_rate_estimating) { + tc_print_rate(PRINT_ANY, "avg_dq_rate", " avg_dq_rate %s", + st->class_stats.avg_dq_rate); + } print_nl(); - print_uint(PRINT_ANY, "new_flow_count", " new_flow_count %u", - st->new_flow_count); - print_uint(PRINT_ANY, "new_flows_len", " new_flows_len %u", - st->new_flows_len); - print_uint(PRINT_ANY, "old_flows_len", " old_flows_len %u", - st->old_flows_len); - print_uint(PRINT_ANY, "memory_used", " memory_used %u", - st->memory_usage); + } + =20 return 0; =20 diff --git a/tc/q_pie.c b/tc/q_pie.c index 04c9aa61..97690d49 100644 --- a/tc/q_pie.c +++ b/tc/q_pie.c @@ -220,8 +220,8 @@ static int pie_print_xstats(const struct qdisc_util *qu= , FILE *f, print_string(PRINT_FP, NULL, " delay %s", sprint_time(st->delay, b1)); =20 if (st->dq_rate_estimating) - print_uint(PRINT_ANY, "avg_dq_rate", " avg_dq_rate %u", - st->avg_dq_rate); + tc_print_rate(PRINT_ANY, "avg_dq_rate", " avg_dq_rate %s", + st->avg_dq_rate); =20 print_nl(); print_uint(PRINT_ANY, "pkts_in", " pkts_in %u", st->packets_in); --=20 2.34.1