Regarding my previous post, latest version is now v1.0.3 and I believe it's best to just git clone again or just get the latest release.
I added some improvements to the install.sh script (see c5f39ef for the details):
Priority order: wget → curl → uclient-fetch.
wget and curl remain first because they provide better progress output
and are more widely available outside of OpenWrt.
Instead of manually choosing the binary from Releases, download the Source code(zip), unzip it, and run the install.sh. I hope it'll work out of the box for you.
If you have some spare time to pull the latest version and see if the throughput numbers finally show up for your cake_mq setup, I’d really appreciate it!
Thanks again for the continuous updates and improvements much appreciated.
I will remove the previous installation and reinstall v1.0.3 using the install.sh script from the source archive as you suggested.
For context, my setup is running OpenWrt with cake_mq (multi-queue) enabled on a 900 Mbit interface, so the issue I previously observed was specifically related to the total TX rate showing 0 B/s while the child cake instances were active.
After reinstalling v1.0.3, I will:
• generate sustained traffic
• compare the header TX rate with tc -s qdisc show
• verify whether the aggregated bandwidth now reflects the sum of the child qdiscs
I’ll report back with precise feedback.
Thanks again for actively supporting cake_mq setups — I know they are less common.
For additional reference, here is a Waveform bufferbloat test under full load. The line remains stable (A+, 0 ms increase under load), confirming CAKE is working correctly with cake_mq.
Can you show me the full outputs of both your tc -s qdisc and tc -s -j qdisc?
The tc outputs will look like this.
I saw from one of your screenshots that your ifb4eth1 is wrongly detected as [EGRESS], so I want to make sure if it's a bug from cake-stats or it's how your cake_mq is configured.
I also feel like it's a bug because looking at your screenshot (the ifb4eth1 one), the bandwidth for each table isn't usually how cake splits bandwidth for diffserv4.
In your screenshot:
Bulk = 375Mbit
Best Effort = 187500Kbit
Video = 187500Kbit
Voice = 250Mbit
According to the manpage, the diffserv4 mode is supposed to be like this:
diffserv4
Provides a general-purpose Diffserv implementation with
four tins:
• Bulk (CS1, LE in kernel v5.9+), 6.25% threshold,
generally low priority.
• Best Effort (general), 100% threshold.
• Video (AF4x, AF3x, CS3, AF2x, CS2, TOS4, TOS1), 50%
threshold.
• Voice (CS7, CS6, EF, VA, CS5, CS4), 25% threshold.
If you see from the header bw 750Mbit, the Best Effort table should show 750Mbit since the manpage mentioned "Best Effort (general), 100% threshold.", so seeing your tc outputs will save a lot of time finding where things went wrong.
Unfortunately, this bug currently happens only for cake_mq, so I couldn't reproduce it since my OpenWrt doesn't support cake_mq yet.
• tc -s qdisc show dev eth1
• tc -s qdisc show dev ifb4eth1
• tc -s -j qdisc show dev eth1
• tc -s -j qdisc show dev ifb4eth1
Both eth1 (egress) and ifb4eth1 (ingress) are running cake_mq with 4 hardware queues.
Configured bandwidth: 650Mbit
From what I understand, cake_mq appears to split the 650Mbit bandwidth across the 4 hardware queues (~162.5Mbit each) and then apply diffserv4 per queue instance rather than globally.
That would explain why the tin thresholds do not match the expected diffserv4 percentages from the manpage (for example, Best Effort not showing the full 650Mbit in each instance).
Could you confirm whether this is expected cake_mq behaviour, or if this points to a cake-stats detection issue?
root@N5105_2:~# tc -s -j qdisc show dev eth1
[{"kind":"cake_mq","handle":"8038:","root":true,"options":{"bandwidth":81250000,"diffserv":"diffserv4","flowmode":"flows","nat":true,"wash":false,"ingress":false,"ack-filter":"disabled","split_gso":true,"rtt":20000,"raw":false,"atm":"noatm","overhead":4,"mpu":84,"fwmark":"0"},"bytes":2393576756,"packets":2942537,"drops":1887,"overlimits":4242658,"requeues":0,"backlog":0,"qlen":0},{"kind":"cake","handle":"0:","parent":"8038:4","options":{"bandwidth":81250000,"diffserv":"diffserv4","flowmode":"flows","nat":true,"wash":false,"ingress":false,"ack-filter":"disabled","split_gso":true,"rtt":20000,"raw":false,"atm":"noatm","overhead":4,"mpu":84,"fwmark":"0"},"bytes":682065036,"packets":855226,"drops":830,"overlimits":1235869,"requeues":0,"backlog":0,"qlen":0,"memory_used":3115008,"memory_limit":6500000,"capacity_estimate":0,"min_network_size":34,"max_network_size":1500,"min_adj_size":84,"max_adj_size":1504,"active_queues":1,"avg_hdr_offset":14,"tins":[{"threshold_rate":5078125,"sent_bytes":0,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":0,"avg_delay_us":0,"base_delay_us":0,"sent_packets":0,"way_indirect_hits":0,"way_misses":0,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":0,"flow_quantum":1239},{"threshold_rate":81250000,"sent_bytes":683212124,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":334,"avg_delay_us":97,"base_delay_us":2,"sent_packets":855888,"way_indirect_hits":0,"way_misses":142,"way_collisions":0,"drops":830,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":1,"unresponsive_flows":0,"max_pkt_len":66884,"flow_quantum":1514},{"threshold_rate":27083333,"sent_bytes":53001,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":75,"avg_delay_us":4,"base_delay_us":0,"sent_packets":155,"way_indirect_hits":0,"way_misses":7,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":2708,"flow_quantum":1514},{"threshold_rate":81250000,"sent_bytes":2197,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":3,"avg_delay_us":0,"base_delay_us":0,"sent_packets":13,"way_indirect_hits":0,"way_misses":1,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":1,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":255,"flow_quantum":1514}]},{"kind":"cake","handle":"0:","parent":"8038:3","options":{"bandwidth":81250000,"diffserv":"diffserv4","flowmode":"flows","nat":true,"wash":false,"ingress":false,"ack-filter":"disabled","split_gso":true,"rtt":20000,"raw":false,"atm":"noatm","overhead":4,"mpu":84,"fwmark":"0"},"bytes":697559831,"packets":1019902,"drops":697,"overlimits":1362003,"requeues":0,"backlog":0,"qlen":0,"memory_used":1973504,"memory_limit":6500000,"capacity_estimate":0,"min_network_size":40,"max_network_size":1500,"min_adj_size":84,"max_adj_size":1504,"active_queues":1,"avg_hdr_offset":14,"tins":[{"threshold_rate":5078125,"sent_bytes":0,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":0,"avg_delay_us":0,"base_delay_us":0,"sent_packets":0,"way_indirect_hits":0,"way_misses":0,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":0,"flow_quantum":1239},{"threshold_rate":81250000,"sent_bytes":698546319,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":131,"avg_delay_us":56,"base_delay_us":1,"sent_packets":1020552,"way_indirect_hits":0,"way_misses":106,"way_collisions":0,"drops":697,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":1,"unresponsive_flows":0,"max_pkt_len":66884,"flow_quantum":1514},{"threshold_rate":20312500,"sent_bytes":23996,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":82,"avg_delay_us":4,"base_delay_us":1,"sent_packets":47,"way_indirect_hits":0,"way_misses":10,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":1853,"flow_quantum":1514},{"threshold_rate":20312500,"sent_bytes":0,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":0,"avg_delay_us":0,"base_delay_us":0,"sent_packets":0,"way_indirect_hits":0,"way_misses":0,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":0,"flow_quantum":1514}]},{"kind":"cake","handle":"0:","parent":"8038:2","options":{"bandwidth":81250000,"diffserv":"diffserv4","flowmode":"flows","nat":true,"wash":false,"ingress":false,"ack-filter":"disabled","split_gso":true,"rtt":20000,"raw":false,"atm":"noatm","overhead":4,"mpu":84,"fwmark":"0"},"bytes":524252251,"packets":665206,"drops":195,"overlimits":874210,"requeues":0,"backlog":0,"qlen":0,"memory_used":1510912,"memory_limit":6500000,"capacity_estimate":0,"min_network_size":40,"max_network_size":1500,"min_adj_size":84,"max_adj_size":1504,"active_queues":2,"avg_hdr_offset":14,"tins":[{"threshold_rate":5078125,"sent_bytes":0,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":0,"avg_delay_us":0,"base_delay_us":0,"sent_packets":0,"way_indirect_hits":0,"way_misses":0,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":0,"flow_quantum":1239},{"threshold_rate":27083333,"sent_bytes":524433017,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":70,"avg_delay_us":29,"base_delay_us":0,"sent_packets":665116,"way_indirect_hits":6,"way_misses":121,"way_collisions":0,"drops":195,"ecn_mark":0,"ack_drops":0,"sparse_flows":2,"bulk_flows":1,"unresponsive_flows":0,"max_pkt_len":63976,"flow_quantum":1514},{"threshold_rate":40625000,"sent_bytes":102469,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":70,"avg_delay_us":5,"base_delay_us":1,"sent_packets":282,"way_indirect_hits":0,"way_misses":21,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":3999,"flow_quantum":1514},{"threshold_rate":27083333,"sent_bytes":295,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":0,"avg_delay_us":0,"base_delay_us":0,"sent_packets":3,"way_indirect_hits":0,"way_misses":2,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":132,"flow_quantum":1514}]},{"kind":"cake","handle":"0:","parent":"8038:1","options":{"bandwidth":81250000,"diffserv":"diffserv4","flowmode":"flows","nat":true,"wash":false,"ingress":false,"ack-filter":"disabled","split_gso":true,"rtt":20000,"raw":false,"atm":"noatm","overhead":4,"mpu":84,"fwmark":"0"},"bytes":489699638,"packets":402203,"drops":165,"overlimits":770576,"requeues":0,"backlog":0,"qlen":0,"memory_used":919808,"memory_limit":6500000,"capacity_estimate":0,"min_network_size":28,"max_network_size":1500,"min_adj_size":84,"max_adj_size":1504,"active_queues":2,"avg_hdr_offset":14,"tins":[{"threshold_rate":5078125,"sent_bytes":0,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":0,"avg_delay_us":0,"base_delay_us":0,"sent_packets":0,"way_indirect_hits":0,"way_misses":0,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":0,"flow_quantum":1239},{"threshold_rate":40625000,"sent_bytes":489916111,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":352,"avg_delay_us":84,"base_delay_us":0,"sent_packets":402318,"way_indirect_hits":0,"way_misses":109,"way_collisions":0,"drops":165,"ecn_mark":0,"ack_drops":0,"sparse_flows":1,"bulk_flows":1,"unresponsive_flows":0,"max_pkt_len":66884,"flow_quantum":1514},{"threshold_rate":40625000,"sent_bytes":17717,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":55,"avg_delay_us":1,"base_delay_us":0,"sent_packets":26,"way_indirect_hits":0,"way_misses":4,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":1377,"flow_quantum":1514},{"threshold_rate":40625000,"sent_bytes":1948,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":3,"avg_delay_us":0,"base_delay_us":0,"sent_packets":24,"way_indirect_hits":0,"way_misses":4,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":582,"flow_quantum":1514}]},{"kind":"ingress","handle":"ffff:","parent":"ffff:fff1","options":{},"bytes":2679812560,"packets":2551066,"drops":0,"overlimits":0,"requeues":0,"backlog":0,"qlen":0}]
=== tc -s -j qdisc show dev ifb4eth1 ===
root@N5105_2:~# tc -s -j qdisc show dev ifb4eth1
[{"kind":"cake_mq","handle":"803a:","root":true,"options":{"bandwidth":81250000,"diffserv":"diffserv4","flowmode":"flows","nat":true,"wash":false,"ingress":false,"ack-filter":"disabled","split_gso":true,"rtt":20000,"raw":false,"atm":"noatm","overhead":4,"mpu":84,"fwmark":"0"},"bytes":2557630963,"packets":2429875,"drops":125092,"overlimits":3080675,"requeues":0,"backlog":0,"qlen":0},{"kind":"cake","handle":"0:","parent":"803a:4","options":{"bandwidth":81250000,"diffserv":"diffserv4","flowmode":"flows","nat":true,"wash":false,"ingress":false,"ack-filter":"disabled","split_gso":true,"rtt":20000,"raw":false,"atm":"noatm","overhead":4,"mpu":84,"fwmark":"0"},"bytes":631948140,"packets":582393,"drops":33222,"overlimits":723777,"requeues":0,"backlog":0,"qlen":0,"memory_used":3264768,"memory_limit":6500000,"capacity_estimate":0,"min_network_size":46,"max_network_size":1500,"min_adj_size":84,"max_adj_size":1504,"active_queues":1,"avg_hdr_offset":14,"tins":[{"threshold_rate":5078125,"sent_bytes":0,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":0,"avg_delay_us":0,"base_delay_us":0,"sent_packets":0,"way_indirect_hits":0,"way_misses":0,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":0,"flow_quantum":1239},{"threshold_rate":81250000,"sent_bytes":682167382,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":43,"avg_delay_us":5,"base_delay_us":0,"sent_packets":615291,"way_indirect_hits":0,"way_misses":195,"way_collisions":0,"drops":33222,"ecn_mark":0,"ack_drops":0,"sparse_flows":1,"bulk_flows":1,"unresponsive_flows":0,"max_pkt_len":34822,"flow_quantum":1514},{"threshold_rate":27083333,"sent_bytes":45366,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":63,"avg_delay_us":5,"base_delay_us":1,"sent_packets":126,"way_indirect_hits":0,"way_misses":20,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":2584,"flow_quantum":1514},{"threshold_rate":81250000,"sent_bytes":28702,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":20,"avg_delay_us":2,"base_delay_us":1,"sent_packets":198,"way_indirect_hits":0,"way_misses":10,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":1,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":285,"flow_quantum":1514}]},{"kind":"cake","handle":"0:","parent":"803a:3","options":{"bandwidth":81250000,"diffserv":"diffserv4","flowmode":"flows","nat":true,"wash":false,"ingress":false,"ack-filter":"disabled","split_gso":true,"rtt":20000,"raw":false,"atm":"noatm","overhead":4,"mpu":84,"fwmark":"0"},"bytes":760431380,"packets":920787,"drops":42417,"overlimits":1235044,"requeues":0,"backlog":0,"qlen":0,"memory_used":5241600,"memory_limit":6500000,"capacity_estimate":0,"min_network_size":46,"max_network_size":1500,"min_adj_size":84,"max_adj_size":1504,"active_queues":4,"avg_hdr_offset":14,"tins":[{"threshold_rate":5078125,"sent_bytes":0,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":0,"avg_delay_us":0,"base_delay_us":0,"sent_packets":0,"way_indirect_hits":0,"way_misses":0,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":0,"flow_quantum":1239},{"threshold_rate":27083333,"sent_bytes":824549608,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":388,"avg_delay_us":77,"base_delay_us":0,"sent_packets":962869,"way_indirect_hits":0,"way_misses":136,"way_collisions":0,"drops":42417,"ecn_mark":0,"ack_drops":0,"sparse_flows":1,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":36336,"flow_quantum":1514},{"threshold_rate":20312500,"sent_bytes":91880,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":96,"avg_delay_us":9,"base_delay_us":1,"sent_packets":317,"way_indirect_hits":0,"way_misses":30,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":2168,"flow_quantum":1514},{"threshold_rate":20312500,"sent_bytes":3495,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":6,"avg_delay_us":0,"base_delay_us":0,"sent_packets":18,"way_indirect_hits":0,"way_misses":8,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":415,"flow_quantum":1514}]},{"kind":"cake","handle":"0:","parent":"803a:2","options":{"bandwidth":81250000,"diffserv":"diffserv4","flowmode":"flows","nat":true,"wash":false,"ingress":false,"ack-filter":"disabled","split_gso":true,"rtt":20000,"raw":false,"atm":"noatm","overhead":4,"mpu":84,"fwmark":"0"},"bytes":669586660,"packets":543150,"drops":35865,"overlimits":708583,"requeues":0,"backlog":0,"qlen":0,"memory_used":6609408,"memory_limit":6500000,"capacity_estimate":0,"min_network_size":46,"max_network_size":1500,"min_adj_size":84,"max_adj_size":1504,"active_queues":3,"avg_hdr_offset":14,"tins":[{"threshold_rate":5078125,"sent_bytes":0,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":0,"avg_delay_us":0,"base_delay_us":0,"sent_packets":0,"way_indirect_hits":0,"way_misses":0,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":0,"flow_quantum":1239},{"threshold_rate":27083333,"sent_bytes":723652284,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":43,"avg_delay_us":8,"base_delay_us":1,"sent_packets":578780,"way_indirect_hits":0,"way_misses":121,"way_collisions":0,"drops":35865,"ecn_mark":0,"ack_drops":0,"sparse_flows":1,"bulk_flows":1,"unresponsive_flows":0,"max_pkt_len":39364,"flow_quantum":1514},{"threshold_rate":27083333,"sent_bytes":187171,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":234,"avg_delay_us":36,"base_delay_us":2,"sent_packets":187,"way_indirect_hits":0,"way_misses":10,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":14741,"flow_quantum":1514},{"threshold_rate":20312500,"sent_bytes":41432,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":173,"avg_delay_us":10,"base_delay_us":2,"sent_packets":48,"way_indirect_hits":0,"way_misses":5,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":11628,"flow_quantum":1514}]},{"kind":"cake","handle":"0:","parent":"803a:1","options":{"bandwidth":81250000,"diffserv":"diffserv4","flowmode":"flows","nat":true,"wash":false,"ingress":false,"ack-filter":"disabled","split_gso":true,"rtt":20000,"raw":false,"atm":"noatm","overhead":4,"mpu":84,"fwmark":"0"},"bytes":495664783,"packets":383545,"drops":13588,"overlimits":413271,"requeues":0,"backlog":0,"qlen":0,"memory_used":2163200,"memory_limit":6500000,"capacity_estimate":0,"min_network_size":46,"max_network_size":1500,"min_adj_size":84,"max_adj_size":1504,"active_queues":1,"avg_hdr_offset":14,"tins":[{"threshold_rate":5078125,"sent_bytes":0,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":0,"avg_delay_us":0,"base_delay_us":0,"sent_packets":0,"way_indirect_hits":0,"way_misses":0,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":0,"flow_quantum":1239},{"threshold_rate":40625000,"sent_bytes":515675702,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":47,"avg_delay_us":6,"base_delay_us":1,"sent_packets":388264,"way_indirect_hits":0,"way_misses":130,"way_collisions":0,"drops":13588,"ecn_mark":0,"ack_drops":0,"sparse_flows":1,"bulk_flows":1,"unresponsive_flows":0,"max_pkt_len":34822,"flow_quantum":1514},{"threshold_rate":40625000,"sent_bytes":25430,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":66,"avg_delay_us":2,"base_delay_us":1,"sent_packets":50,"way_indirect_hits":0,"way_misses":8,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":0,"unresponsive_flows":0,"max_pkt_len":5288,"flow_quantum":1514},{"threshold_rate":81250000,"sent_bytes":535115,"backlog_bytes":0,"target_us":1000,"interval_us":20000,"peak_delay_us":13,"avg_delay_us":2,"base_delay_us":0,"sent_packets":8819,"way_indirect_hits":0,"way_misses":6,"way_collisions":0,"drops":0,"ecn_mark":0,"ack_drops":0,"sparse_flows":0,"bulk_flows":1,"unresponsive_flows":0,"max_pkt_len":2932,"flow_quantum":1514}]}]
root@N5105_2:~#
Hmm, that means the tc-cake manpage isn't 100% accurate (I mean.. not for cake_mq) if cake_mq separates the bandwidth like that.
I'll see what I can do after comparing your tc outputs with the cake-stats code and I'll let you know when there's a new version with the new fix included.
From what I understand, cake_mq appears to split the 650Mbit bandwidth across the 4 hardware queues (~162.5Mbit each) and then apply diffserv4 per queue instance rather than globally.
That would explain why the tin thresholds do not match the expected diffserv4 percentages from the manpage (for example, Best Effort not showing the full 650Mbit in each instance).
Could you confirm whether this is expected cake_mq behaviour, or if this points to a cake-stats detection issue?
I've pushed a quick fix (see 60c3869).
Now cake-stats should be able to tell if an interface is [INGRESS]/[EGRESS] properly (hopefully).
You can simply use sh uninstall.sh and then sh install.sh to install the latest version, or if you prefer to git clone again, you can do that as well.
Let me know if cake-stats still wrongly detects ifb4eth1 as [EGRESS].
It seems that patch will affect how cake_mq shows stats to tc, but cake-stats should be able to parse data correctly when the patch got accepted, as long as they don't change how cake or cake_mq prints its statistics when we use tc -s qdisc.
That's the install.sh version, not the cake-stats binary version, so you can safely ignore that.
The install.sh will always download the latest version from GitHub Releases and install it as a service automatically. You can verify it by running /usr/bin/cake-stats -version from your OpenWrt terminal.
In cake-stats the tin thresholds appear consistent with a per-queue rate rather than the full link rate, which seems to match what I observed earlier when using cake_mq.
Given a 600–650 Mbit configured rate and 4 hardware queues, this suggests that each queue is effectively operating on ~150–160 Mbit before diffserv classification.
So my understanding is that cake_mq distributes the bandwidth across the hardware queues and each queue then runs its own CAKE instance with diffserv4.
Does that match the intended behaviour of cake_mq, or should the tin thresholds still reflect the full link rate?
Also thanks for mentioning the kernel patch for the cake_mq rate handling — I saw the discussion on lore.kernel.org and that may explain the behaviour I was seeing earlier.
I can't really say for sure since my OpenWrt doesn't support cake_mq, but the easiest way to confirm if cake-stats works as expected would be to just compare your tc -s qdisc output side-by-side with how cake-stats displays the table.
For example, you can check ifb4eth1 from your tc output, and compare the table shown by cake-stats. If the cake-stats bandwidth for each row (i.e. Best Effort row) shows accurate number like from your tc, then you can assume cake-stats is working as expected.
After I checked everything, it seems cake-stats parses the statistics properly.
If you see carefully from your screenshot, that's not a bug.
The UI shows dropped: 41 and you can count manually (drops: 7 + ack_drop: 34 = dropped: 41).
I've added some more tests and some fixes to the install.sh script (see bb2b992 and the full changelog).
To cleanly update cake-stats, you can follow the How to Update section here.