Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net_sched: sch_fq: add three drop_reason

Add three new drop_reason, more precise than generic QDISC_DROP:

"tc -s qd" show aggregate counters, it might be more useful
to use drop_reason infrastructure for bug hunting.

1) SKB_DROP_REASON_FQ_BAND_LIMIT
Whenever a packet is added while its band limit is hit.
Corresponding value in "tc -s qd" is bandX_drops XXXX

2) SKB_DROP_REASON_FQ_HORIZON_LIMIT
Whenever a packet has a timestamp too far in the future.
Corresponding value in "tc -s qd" is horizon_drops XXXX

3) SKB_DROP_REASON_FQ_FLOW_LIMIT
Whenever a flow has reached its limit.
Corresponding value in "tc -s qd" is flows_plimit XXXX

Tested:
tc qd replace dev eth1 root fq flow_limit 10 limit 100000
perf record -a -e skb:kfree_skb sleep 1; perf script

udp_stream 12329 [004] 216.929492: skb:kfree_skb: skbaddr=0xffff888eabe17e00 rx_sk=(nil) protocol=34525 location=__dev_queue_xmit+0x9d9 reason: FQ_FLOW_LIMIT
udp_stream 12385 [006] 216.929593: skb:kfree_skb: skbaddr=0xffff888ef8827f00 rx_sk=(nil) protocol=34525 location=__dev_queue_xmit+0x9d9 reason: FQ_FLOW_LIMIT
udp_stream 12389 [005] 216.929871: skb:kfree_skb: skbaddr=0xffff888ecb9ba500 rx_sk=(nil) protocol=34525 location=__dev_queue_xmit+0x9d9 reason: FQ_FLOW_LIMIT
udp_stream 12316 [009] 216.930398: skb:kfree_skb: skbaddr=0xffff888eca286b00 rx_sk=(nil) protocol=34525 location=__dev_queue_xmit+0x9d9 reason: FQ_FLOW_LIMIT
udp_stream 12400 [008] 216.930490: skb:kfree_skb: skbaddr=0xffff888eabf93d00 rx_sk=(nil) protocol=34525 location=__dev_queue_xmit+0x9d9 reason: FQ_FLOW_LIMIT

tc qd replace dev eth1 root fq flow_limit 100 limit 10000
perf record -a -e skb:kfree_skb sleep 1; perf script

udp_stream 18074 [001] 1058.318040: skb:kfree_skb: skbaddr=0xffffa23c881fc000 rx_sk=(nil) protocol=34525 location=__dev_queue_xmit+0x9d9 reason: FQ_BAND_LIMIT
udp_stream 18126 [005] 1058.320651: skb:kfree_skb: skbaddr=0xffffa23c6aad4000 rx_sk=(nil) protocol=34525 location=__dev_queue_xmit+0x9d9 reason: FQ_BAND_LIMIT
udp_stream 18118 [006] 1058.321065: skb:kfree_skb: skbaddr=0xffffa23df0d48a00 rx_sk=(nil) protocol=34525 location=__dev_queue_xmit+0x9d9 reason: FQ_BAND_LIMIT
udp_stream 18074 [001] 1058.321126: skb:kfree_skb: skbaddr=0xffffa23c881ffa00 rx_sk=(nil) protocol=34525 location=__dev_queue_xmit+0x9d9 reason: FQ_BAND_LIMIT
udp_stream 15815 [003] 1058.321224: skb:kfree_skb: skbaddr=0xffffa23c9835db00 rx_sk=(nil) protocol=34525 location=__dev_queue_xmit+0x9d9 reason: FQ_BAND_LIMIT

tc -s -d qd sh dev eth1
qdisc fq 8023: root refcnt 257 limit 10000p flow_limit 100p buckets 1024 orphan_mask 1023
bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1 weights 589824 196608 65536 quantum 18Kb
initial_quantum 92120b low_rate_threshold 550Kbit refill_delay 40ms
timer_slack 10us horizon 10s horizon_drop
Sent 492439603330 bytes 336953991 pkt (dropped 61724094, overlimits 0 requeues 4463)
backlog 14611228b 9995p requeues 4463
flows 2965 (inactive 1151 throttled 0) band0_pkts 0 band1_pkts 9993 band2_pkts 0
gc 6347 highprio 0 fastpath 30 throttled 5 latency 2.32us flows_plimit 7403693
band1_drops 54320401

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Victor Nogueira <victor@mojatatu.com>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20241204171950.89829-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
5765c7f6 f9305949

+36 -4
+18
include/net/dropreason-core.h
··· 58 58 FN(TC_EGRESS) \ 59 59 FN(SECURITY_HOOK) \ 60 60 FN(QDISC_DROP) \ 61 + FN(FQ_BAND_LIMIT) \ 62 + FN(FQ_HORIZON_LIMIT) \ 63 + FN(FQ_FLOW_LIMIT) \ 61 64 FN(CPU_BACKLOG) \ 62 65 FN(XDP) \ 63 66 FN(TC_INGRESS) \ ··· 314 311 * failed to enqueue to current qdisc) 315 312 */ 316 313 SKB_DROP_REASON_QDISC_DROP, 314 + /** 315 + * @SKB_DROP_REASON_FQ_BAND_LIMIT: dropped by fq qdisc when per band 316 + * limit is reached. 317 + */ 318 + SKB_DROP_REASON_FQ_BAND_LIMIT, 319 + /** 320 + * @SKB_DROP_REASON_FQ_HORIZON_LIMIT: dropped by fq qdisc when packet 321 + * timestamp is too far in the future. 322 + */ 323 + SKB_DROP_REASON_FQ_HORIZON_LIMIT, 324 + /** 325 + * @SKB_DROP_REASON_FQ_FLOW_LIMIT: dropped by fq qdisc when a flow 326 + * exceeds its limits. 327 + */ 328 + SKB_DROP_REASON_FQ_FLOW_LIMIT, 317 329 /** 318 330 * @SKB_DROP_REASON_CPU_BACKLOG: failed to enqueue the skb to the per CPU 319 331 * backlog queue. This can be caused by backlog queue full (see
+8
include/net/sch_generic.h
··· 1245 1245 return NET_XMIT_DROP; 1246 1246 } 1247 1247 1248 + static inline int qdisc_drop_reason(struct sk_buff *skb, struct Qdisc *sch, 1249 + struct sk_buff **to_free, 1250 + enum skb_drop_reason reason) 1251 + { 1252 + tcf_set_drop_reason(skb, reason); 1253 + return qdisc_drop(skb, sch, to_free); 1254 + } 1255 + 1248 1256 static inline int qdisc_drop_all(struct sk_buff *skb, struct Qdisc *sch, 1249 1257 struct sk_buff **to_free) 1250 1258 {
+10 -4
net/sched/sch_fq.c
··· 537 537 return unlikely((s64)skb->tstamp > (s64)(now + q->horizon)); 538 538 } 539 539 540 + #define FQDR(reason) SKB_DROP_REASON_FQ_##reason 541 + 540 542 static int fq_enqueue(struct sk_buff *skb, struct Qdisc *sch, 541 543 struct sk_buff **to_free) 542 544 { ··· 550 548 band = fq_prio2band(q->prio2band, skb->priority & TC_PRIO_MAX); 551 549 if (unlikely(q->band_pkt_count[band] >= sch->limit)) { 552 550 q->stat_band_drops[band]++; 553 - return qdisc_drop(skb, sch, to_free); 551 + return qdisc_drop_reason(skb, sch, to_free, 552 + FQDR(BAND_LIMIT)); 554 553 } 555 554 556 555 now = ktime_get_ns(); ··· 561 558 /* Check if packet timestamp is too far in the future. */ 562 559 if (fq_packet_beyond_horizon(skb, q, now)) { 563 560 if (q->horizon_drop) { 564 - q->stat_horizon_drops++; 565 - return qdisc_drop(skb, sch, to_free); 561 + q->stat_horizon_drops++; 562 + return qdisc_drop_reason(skb, sch, to_free, 563 + FQDR(HORIZON_LIMIT)); 566 564 } 567 565 q->stat_horizon_caps++; 568 566 skb->tstamp = now + q->horizon; ··· 576 572 if (f != &q->internal) { 577 573 if (unlikely(f->qlen >= q->flow_plimit)) { 578 574 q->stat_flows_plimit++; 579 - return qdisc_drop(skb, sch, to_free); 575 + return qdisc_drop_reason(skb, sch, to_free, 576 + FQDR(FLOW_LIMIT)); 580 577 } 581 578 582 579 if (fq_flow_is_detached(f)) { ··· 602 597 603 598 return NET_XMIT_SUCCESS; 604 599 } 600 + #undef FQDR 605 601 606 602 static void fq_check_throttled(struct fq_sched_data *q, u64 now) 607 603 {