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.

Merge branch 'net-sched-refactor-qdisc-drop-reasons-into-dedicated-tracepoint'

Jesper Dangaard Brouer says:

====================
net: sched: refactor qdisc drop reasons into dedicated tracepoint

This series refactors qdisc drop reason handling by introducing a dedicated
enum qdisc_drop_reason and trace_qdisc_drop tracepoint, providing qdisc
layer drop diagnostics with direct qdisc context visibility.

Background:
-----------
Identifying which qdisc dropped a packet via skb_drop_reason is difficult.
Normally, the kfree_skb tracepoint caller "location" hints at the dropping
code, but qdisc drops happen at a central point (__dev_queue_xmit), making
this unusable. As a workaround, commits 5765c7f6e317 ("net_sched: sch_fq:
add three drop_reason") and a42d71e322a8 ("net_sched: sch_cake: Add drop
reasons") encoded qdisc names directly in the drop reason enums.

This series provides a cleaner solution by creating a dedicated qdisc
tracepoint that naturally includes qdisc context (handle, parent, kind).

Solution:
---------
Create a new tracepoint trace_qdisc_drop that builds on top of existing
trace_qdisc_enqueue infrastructure. It includes qdisc handle, parent,
qdisc kind (name), and device information directly.

The existing SKB_DROP_REASON_QDISC_DROP is retained for backwards
compatibility via kfree_skb_reason(). The qdisc-specific drop reasons
(QDISC_DROP_*) provide fine-grained detail via the new tracepoint.
The enum uses subsystem encoding (offset by SKB_DROP_REASON_SUBSYS_QDISC)
to catch type mismatches during debugging.

This implements the alternative approach described in:
https://lore.kernel.org/all/6be17a08-f8aa-4f91-9bd0-d9e1f0a92d90@kernel.org/
====================

Link: https://patch.msgid.link/177211325634.3011628.9343837509740374154.stgit@firesoul
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+278 -112
+4 -44
include/net/dropreason-core.h
··· 68 68 FN(SECURITY_HOOK) \ 69 69 FN(QDISC_DROP) \ 70 70 FN(QDISC_BURST_DROP) \ 71 - FN(QDISC_OVERLIMIT) \ 72 - FN(QDISC_CONGESTED) \ 73 - FN(CAKE_FLOOD) \ 74 - FN(FQ_BAND_LIMIT) \ 75 - FN(FQ_HORIZON_LIMIT) \ 76 - FN(FQ_FLOW_LIMIT) \ 77 71 FN(CPU_BACKLOG) \ 78 72 FN(XDP) \ 79 73 FN(TC_INGRESS) \ ··· 121 127 FN(CANFD_RX_INVALID_FRAME) \ 122 128 FN(CANXL_RX_INVALID_FRAME) \ 123 129 FN(PFMEMALLOC) \ 124 - FN(DUALPI2_STEP_DROP) \ 125 130 FN(PSP_INPUT) \ 126 131 FN(PSP_OUTPUT) \ 127 132 FNe(MAX) ··· 364 371 /** @SKB_DROP_REASON_SECURITY_HOOK: dropped due to security HOOK */ 365 372 SKB_DROP_REASON_SECURITY_HOOK, 366 373 /** 367 - * @SKB_DROP_REASON_QDISC_DROP: dropped by qdisc when packet outputting ( 368 - * failed to enqueue to current qdisc) 374 + * @SKB_DROP_REASON_QDISC_DROP: dropped by qdisc during enqueue or 375 + * dequeue. More specific drop reasons are available via the 376 + * qdisc:qdisc_drop tracepoint, which also provides qdisc handle 377 + * and name for identifying the source. 369 378 */ 370 379 SKB_DROP_REASON_QDISC_DROP, 371 380 /** ··· 375 380 * limit is hit. 376 381 */ 377 382 SKB_DROP_REASON_QDISC_BURST_DROP, 378 - /** 379 - * @SKB_DROP_REASON_QDISC_OVERLIMIT: dropped by qdisc when a qdisc 380 - * instance exceeds its total buffer size limit. 381 - */ 382 - SKB_DROP_REASON_QDISC_OVERLIMIT, 383 - /** 384 - * @SKB_DROP_REASON_QDISC_CONGESTED: dropped by a qdisc AQM algorithm 385 - * due to congestion. 386 - */ 387 - SKB_DROP_REASON_QDISC_CONGESTED, 388 - /** 389 - * @SKB_DROP_REASON_CAKE_FLOOD: dropped by the flood protection part of 390 - * CAKE qdisc AQM algorithm (BLUE). 391 - */ 392 - SKB_DROP_REASON_CAKE_FLOOD, 393 - /** 394 - * @SKB_DROP_REASON_FQ_BAND_LIMIT: dropped by fq qdisc when per band 395 - * limit is reached. 396 - */ 397 - SKB_DROP_REASON_FQ_BAND_LIMIT, 398 - /** 399 - * @SKB_DROP_REASON_FQ_HORIZON_LIMIT: dropped by fq qdisc when packet 400 - * timestamp is too far in the future. 401 - */ 402 - SKB_DROP_REASON_FQ_HORIZON_LIMIT, 403 - /** 404 - * @SKB_DROP_REASON_FQ_FLOW_LIMIT: dropped by fq qdisc when a flow 405 - * exceeds its limits. 406 - */ 407 - SKB_DROP_REASON_FQ_FLOW_LIMIT, 408 383 /** 409 384 * @SKB_DROP_REASON_CPU_BACKLOG: failed to enqueue the skb to the per CPU 410 385 * backlog queue. This can be caused by backlog queue full (see ··· 578 613 * reached a path or socket not eligible for use of memory reserves 579 614 */ 580 615 SKB_DROP_REASON_PFMEMALLOC, 581 - /** 582 - * @SKB_DROP_REASON_DUALPI2_STEP_DROP: dropped by the step drop 583 - * threshold of DualPI2 qdisc. 584 - */ 585 - SKB_DROP_REASON_DUALPI2_STEP_DROP, 586 616 /** @SKB_DROP_REASON_PSP_INPUT: PSP input checks failed */ 587 617 SKB_DROP_REASON_PSP_INPUT, 588 618 /** @SKB_DROP_REASON_PSP_OUTPUT: PSP output checks failed */
+114
include/net/dropreason-qdisc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + 3 + #ifndef _LINUX_DROPREASON_QDISC_H 4 + #define _LINUX_DROPREASON_QDISC_H 5 + #include <net/dropreason.h> 6 + 7 + #define DEFINE_QDISC_DROP_REASON(FN, FNe) \ 8 + FN(UNSPEC) \ 9 + FN(GENERIC) \ 10 + FN(OVERLIMIT) \ 11 + FN(CONGESTED) \ 12 + FN(MAXFLOWS) \ 13 + FN(FLOOD_PROTECTION) \ 14 + FN(BAND_LIMIT) \ 15 + FN(HORIZON_LIMIT) \ 16 + FN(FLOW_LIMIT) \ 17 + FN(L4S_STEP_NON_ECN) \ 18 + FNe(MAX) 19 + 20 + #undef FN 21 + #undef FNe 22 + #define FN(reason) QDISC_DROP_##reason, 23 + #define FNe(reason) QDISC_DROP_##reason 24 + 25 + /** 26 + * enum qdisc_drop_reason - reason why a qdisc dropped a packet 27 + * 28 + * Qdisc-specific drop reasons for packet drops that occur within the 29 + * traffic control (TC) queueing discipline layer. These reasons provide 30 + * detailed diagnostics about why packets were dropped by various qdisc 31 + * algorithms, enabling fine-grained monitoring and troubleshooting of 32 + * queue behavior. 33 + */ 34 + enum qdisc_drop_reason { 35 + /** 36 + * @QDISC_DROP_UNSPEC: unspecified/invalid qdisc drop reason. 37 + * Value 0 serves as analogous to SKB_NOT_DROPPED_YET for enum skb_drop_reason. 38 + * Used for catching zero-initialized drop_reason fields. 39 + */ 40 + QDISC_DROP_UNSPEC = 0, 41 + /** 42 + * @__QDISC_DROP_REASON: subsystem base value for qdisc drop reasons 43 + */ 44 + __QDISC_DROP_REASON = SKB_DROP_REASON_SUBSYS_QDISC << 45 + SKB_DROP_REASON_SUBSYS_SHIFT, 46 + /** 47 + * @QDISC_DROP_GENERIC: generic/default qdisc drop, used when no 48 + * more specific reason applies 49 + */ 50 + QDISC_DROP_GENERIC, 51 + /** 52 + * @QDISC_DROP_OVERLIMIT: packet dropped because the qdisc queue 53 + * length exceeded its configured limit (sch->limit). This typically 54 + * indicates the queue is full and cannot accept more packets. 55 + */ 56 + QDISC_DROP_OVERLIMIT, 57 + /** 58 + * @QDISC_DROP_CONGESTED: packet dropped due to active congestion 59 + * control algorithms (e.g., CoDel, PIE, RED) detecting network 60 + * congestion. The qdisc proactively dropped the packet to signal 61 + * congestion to the sender and prevent bufferbloat. 62 + */ 63 + QDISC_DROP_CONGESTED, 64 + /** 65 + * @QDISC_DROP_MAXFLOWS: packet dropped because the qdisc's flow 66 + * tracking table is full and no free slots are available to allocate 67 + * for a new flow. This indicates flow table exhaustion in flow-based 68 + * qdiscs that maintain per-flow state (e.g., SFQ). 69 + */ 70 + QDISC_DROP_MAXFLOWS, 71 + /** 72 + * @QDISC_DROP_FLOOD_PROTECTION: packet dropped by flood protection 73 + * mechanism detecting unresponsive flows (potential DoS/flood). 74 + * Used by qdiscs implementing probabilistic drop algorithms like 75 + * BLUE (e.g., CAKE's Cobalt AQM). 76 + */ 77 + QDISC_DROP_FLOOD_PROTECTION, 78 + /** 79 + * @QDISC_DROP_BAND_LIMIT: packet dropped because the priority band's 80 + * limit was reached. Used by qdiscs with priority bands that have 81 + * per-band packet limits (e.g., FQ). 82 + */ 83 + QDISC_DROP_BAND_LIMIT, 84 + /** 85 + * @QDISC_DROP_HORIZON_LIMIT: packet dropped because its timestamp 86 + * is too far in the future (beyond the configured horizon). 87 + * Used by qdiscs with time-based scheduling (e.g., FQ). 88 + */ 89 + QDISC_DROP_HORIZON_LIMIT, 90 + /** 91 + * @QDISC_DROP_FLOW_LIMIT: packet dropped because an individual flow 92 + * exceeded its per-flow packet/depth limit. Used by FQ and SFQ qdiscs 93 + * to enforce per-flow fairness and prevent a single flow from 94 + * monopolizing queue resources. 95 + */ 96 + QDISC_DROP_FLOW_LIMIT, 97 + /** 98 + * @QDISC_DROP_L4S_STEP_NON_ECN: DualPI2 qdisc dropped a non-ECN-capable 99 + * packet because the L4S queue delay exceeded the step threshold. 100 + * Since the packet cannot be ECN-marked, it must be dropped to signal 101 + * congestion. See RFC 9332 for the DualQ Coupled AQM step mechanism. 102 + */ 103 + QDISC_DROP_L4S_STEP_NON_ECN, 104 + /** 105 + * @QDISC_DROP_MAX: the maximum of qdisc drop reasons, which 106 + * shouldn't be used as a real 'reason' - only for tracing code gen 107 + */ 108 + QDISC_DROP_MAX, 109 + }; 110 + 111 + #undef FN 112 + #undef FNe 113 + 114 + #endif
+6
include/net/dropreason.h
··· 23 23 */ 24 24 SKB_DROP_REASON_SUBSYS_OPENVSWITCH, 25 25 26 + /** 27 + * @SKB_DROP_REASON_SUBSYS_QDISC: TC qdisc drop reasons, 28 + * see include/net/dropreason-qdisc.h 29 + */ 30 + SKB_DROP_REASON_SUBSYS_QDISC, 31 + 26 32 /** @SKB_DROP_REASON_SUBSYS_NUM: number of subsystems defined */ 27 33 SKB_DROP_REASON_SUBSYS_NUM 28 34 };
+30 -13
include/net/sch_generic.h
··· 20 20 #include <net/rtnetlink.h> 21 21 #include <net/flow_offload.h> 22 22 #include <linux/xarray.h> 23 + #include <net/dropreason-qdisc.h> 23 24 24 25 struct Qdisc_ops; 25 26 struct qdisc_walker; 26 27 struct tcf_walker; 27 28 struct module; 28 29 struct bpf_flow_keys; 30 + struct Qdisc; 31 + struct netdev_queue; 29 32 30 33 struct qdisc_rate_table { 31 34 struct tc_ratespec rate; ··· 1109 1106 return cb; 1110 1107 } 1111 1108 1109 + /* TC classifier accessors - use enum skb_drop_reason */ 1112 1110 static inline enum skb_drop_reason 1113 1111 tcf_get_drop_reason(const struct sk_buff *skb) 1114 1112 { 1115 - return tc_skb_cb(skb)->drop_reason; 1113 + return (enum skb_drop_reason)tc_skb_cb(skb)->drop_reason; 1116 1114 } 1117 1115 1118 1116 static inline void tcf_set_drop_reason(const struct sk_buff *skb, 1119 1117 enum skb_drop_reason reason) 1120 1118 { 1119 + tc_skb_cb(skb)->drop_reason = (enum qdisc_drop_reason)reason; 1120 + } 1121 + 1122 + /* Qdisc accessors - use enum qdisc_drop_reason */ 1123 + static inline enum qdisc_drop_reason 1124 + tcf_get_qdisc_drop_reason(const struct sk_buff *skb) 1125 + { 1126 + return tc_skb_cb(skb)->drop_reason; 1127 + } 1128 + 1129 + static inline void tcf_set_qdisc_drop_reason(const struct sk_buff *skb, 1130 + enum qdisc_drop_reason reason) 1131 + { 1121 1132 tc_skb_cb(skb)->drop_reason = reason; 1122 1133 } 1123 1134 1124 - static inline void tcf_kfree_skb_list(struct sk_buff *skb) 1125 - { 1126 - while (unlikely(skb)) { 1127 - struct sk_buff *next = skb->next; 1135 + void __tcf_kfree_skb_list(struct sk_buff *skb, struct Qdisc *q, 1136 + struct netdev_queue *txq, struct net_device *dev); 1128 1137 1129 - prefetch(next); 1130 - kfree_skb_reason(skb, tcf_get_drop_reason(skb)); 1131 - skb = next; 1132 - } 1138 + static inline void tcf_kfree_skb_list(struct sk_buff *skb, struct Qdisc *q, 1139 + struct netdev_queue *txq, 1140 + struct net_device *dev) 1141 + { 1142 + if (unlikely(skb)) 1143 + __tcf_kfree_skb_list(skb, q, txq, dev); 1133 1144 } 1134 1145 1135 1146 static inline void qdisc_dequeue_drop(struct Qdisc *q, struct sk_buff *skb, 1136 - enum skb_drop_reason reason) 1147 + enum qdisc_drop_reason reason) 1137 1148 { 1138 1149 DEBUG_NET_WARN_ON_ONCE(!(q->flags & TCQ_F_DEQUEUE_DROPS)); 1139 1150 DEBUG_NET_WARN_ON_ONCE(q->flags & TCQ_F_NOLOCK); 1140 1151 1141 - tcf_set_drop_reason(skb, reason); 1152 + tcf_set_qdisc_drop_reason(skb, reason); 1142 1153 skb->next = q->to_free; 1143 1154 q->to_free = skb; 1144 1155 } ··· 1329 1312 1330 1313 static inline int qdisc_drop_reason(struct sk_buff *skb, struct Qdisc *sch, 1331 1314 struct sk_buff **to_free, 1332 - enum skb_drop_reason reason) 1315 + enum qdisc_drop_reason reason) 1333 1316 { 1334 - tcf_set_drop_reason(skb, reason); 1317 + tcf_set_qdisc_drop_reason(skb, reason); 1335 1318 return qdisc_drop(skb, sch, to_free); 1336 1319 } 1337 1320
+51
include/trace/events/qdisc.h
··· 74 74 __entry->ifindex, __entry->handle, __entry->parent, __entry->skbaddr) 75 75 ); 76 76 77 + #undef FN 78 + #undef FNe 79 + #define FN(reason) TRACE_DEFINE_ENUM(QDISC_DROP_##reason); 80 + #define FNe(reason) TRACE_DEFINE_ENUM(QDISC_DROP_##reason); 81 + DEFINE_QDISC_DROP_REASON(FN, FNe) 82 + 83 + #undef FN 84 + #undef FNe 85 + #define FN(reason) { QDISC_DROP_##reason, #reason }, 86 + #define FNe(reason) { QDISC_DROP_##reason, #reason } 87 + 88 + TRACE_EVENT(qdisc_drop, 89 + 90 + TP_PROTO(struct Qdisc *qdisc, const struct netdev_queue *txq, 91 + struct net_device *dev, struct sk_buff *skb, 92 + enum qdisc_drop_reason reason), 93 + 94 + TP_ARGS(qdisc, txq, dev, skb, reason), 95 + 96 + TP_STRUCT__entry( 97 + __field(struct Qdisc *, qdisc) 98 + __field(const struct netdev_queue *, txq) 99 + __field(void *, skbaddr) 100 + __field(int, ifindex) 101 + __field(u32, handle) 102 + __field(u32, parent) 103 + __field(enum qdisc_drop_reason, reason) 104 + __string(kind, qdisc->ops->id) 105 + ), 106 + 107 + TP_fast_assign( 108 + __entry->qdisc = qdisc; 109 + __entry->txq = txq; 110 + __entry->skbaddr = skb; 111 + __entry->ifindex = dev ? dev->ifindex : 0; 112 + __entry->handle = qdisc->handle; 113 + __entry->parent = qdisc->parent; 114 + __entry->reason = reason; 115 + __assign_str(kind); 116 + ), 117 + 118 + TP_printk("drop ifindex=%d kind=%s handle=0x%X parent=0x%X skbaddr=%p reason=%s", 119 + __entry->ifindex, __get_str(kind), __entry->handle, 120 + __entry->parent, __entry->skbaddr, 121 + __print_symbolic(__entry->reason, 122 + DEFINE_QDISC_DROP_REASON(FN, FNe))) 123 + ); 124 + 125 + #undef FN 126 + #undef FNe 127 + 77 128 TRACE_EVENT(qdisc_reset, 78 129 79 130 TP_PROTO(struct Qdisc *q),
+4 -4
net/core/dev.c
··· 4166 4166 4167 4167 qdisc_calculate_pkt_len(skb, q); 4168 4168 4169 - tcf_set_drop_reason(skb, SKB_DROP_REASON_QDISC_DROP); 4169 + tcf_set_qdisc_drop_reason(skb, QDISC_DROP_GENERIC); 4170 4170 4171 4171 if (q->flags & TCQ_F_NOLOCK) { 4172 4172 if (q->flags & TCQ_F_CAN_BYPASS && nolock_qdisc_is_empty(q) && ··· 4274 4274 spin_unlock(root_lock); 4275 4275 4276 4276 free_skbs: 4277 - tcf_kfree_skb_list(to_free); 4278 - tcf_kfree_skb_list(to_free2); 4277 + tcf_kfree_skb_list(to_free, q, txq, dev); 4278 + tcf_kfree_skb_list(to_free2, q, txq, dev); 4279 4279 return rc; 4280 4280 } 4281 4281 ··· 5811 5811 to_free = qdisc_run(q); 5812 5812 if (root_lock) 5813 5813 spin_unlock(root_lock); 5814 - tcf_kfree_skb_list(to_free); 5814 + tcf_kfree_skb_list(to_free, q, NULL, qdisc_dev(q)); 5815 5815 } 5816 5816 5817 5817 rcu_read_unlock();
+13 -13
net/sched/sch_cake.c
··· 497 497 /* Call this with a freshly dequeued packet for possible congestion marking. 498 498 * Returns true as an instruction to drop the packet, false for delivery. 499 499 */ 500 - static enum skb_drop_reason cobalt_should_drop(struct cobalt_vars *vars, 501 - struct cobalt_params *p, 502 - ktime_t now, 503 - struct sk_buff *skb, 504 - u32 bulk_flows) 500 + static enum qdisc_drop_reason cobalt_should_drop(struct cobalt_vars *vars, 501 + struct cobalt_params *p, 502 + ktime_t now, 503 + struct sk_buff *skb, 504 + u32 bulk_flows) 505 505 { 506 - enum skb_drop_reason reason = SKB_NOT_DROPPED_YET; 506 + enum qdisc_drop_reason reason = QDISC_DROP_UNSPEC; 507 507 bool next_due, over_target; 508 508 ktime_t schedule; 509 509 u64 sojourn; ··· 548 548 if (next_due && vars->dropping) { 549 549 /* Use ECN mark if possible, otherwise drop */ 550 550 if (!(vars->ecn_marked = INET_ECN_set_ce(skb))) 551 - reason = SKB_DROP_REASON_QDISC_CONGESTED; 551 + reason = QDISC_DROP_CONGESTED; 552 552 553 553 vars->count++; 554 554 if (!vars->count) ··· 571 571 } 572 572 573 573 /* Simple BLUE implementation. Lack of ECN is deliberate. */ 574 - if (vars->p_drop && reason == SKB_NOT_DROPPED_YET && 574 + if (vars->p_drop && reason == QDISC_DROP_UNSPEC && 575 575 get_random_u32() < vars->p_drop) 576 - reason = SKB_DROP_REASON_CAKE_FLOOD; 576 + reason = QDISC_DROP_FLOOD_PROTECTION; 577 577 578 578 /* Overload the drop_next field as an activity timeout */ 579 579 if (!vars->count) 580 580 vars->drop_next = ktime_add_ns(now, p->interval); 581 - else if (ktime_to_ns(schedule) > 0 && reason == SKB_NOT_DROPPED_YET) 581 + else if (ktime_to_ns(schedule) > 0 && reason == QDISC_DROP_UNSPEC) 582 582 vars->drop_next = now; 583 583 584 584 return reason; ··· 1604 1604 if (q->config->rate_flags & CAKE_FLAG_INGRESS) 1605 1605 cake_advance_shaper(q, b, skb, now, true); 1606 1606 1607 - qdisc_drop_reason(skb, sch, to_free, SKB_DROP_REASON_QDISC_OVERLIMIT); 1607 + qdisc_drop_reason(skb, sch, to_free, QDISC_DROP_OVERLIMIT); 1608 1608 sch->q.qlen--; 1609 1609 1610 1610 cake_heapify(q, 0); ··· 2004 2004 { 2005 2005 struct cake_sched_data *q = qdisc_priv(sch); 2006 2006 struct cake_tin_data *b = &q->tins[q->cur_tin]; 2007 - enum skb_drop_reason reason; 2007 + enum qdisc_drop_reason reason; 2008 2008 ktime_t now = ktime_get(); 2009 2009 struct cake_flow *flow; 2010 2010 struct list_head *head; ··· 2225 2225 !!(q->config->rate_flags & 2226 2226 CAKE_FLAG_INGRESS))); 2227 2227 /* Last packet in queue may be marked, shouldn't be dropped */ 2228 - if (reason == SKB_NOT_DROPPED_YET || !flow->head) 2228 + if (reason == QDISC_DROP_UNSPEC || !flow->head) 2229 2229 break; 2230 2230 2231 2231 /* drop this packet, get another one */
+2 -3
net/sched/sch_codel.c
··· 52 52 { 53 53 struct Qdisc *sch = ctx; 54 54 55 - qdisc_dequeue_drop(sch, skb, SKB_DROP_REASON_QDISC_CONGESTED); 55 + qdisc_dequeue_drop(sch, skb, QDISC_DROP_CONGESTED); 56 56 qdisc_qstats_drop(sch); 57 57 } 58 58 ··· 86 86 } 87 87 q = qdisc_priv(sch); 88 88 q->drop_overlimit++; 89 - return qdisc_drop_reason(skb, sch, to_free, 90 - SKB_DROP_REASON_QDISC_OVERLIMIT); 89 + return qdisc_drop_reason(skb, sch, to_free, QDISC_DROP_OVERLIMIT); 91 90 } 92 91 93 92 static const struct nla_policy codel_policy[TCA_CODEL_MAX + 1] = {
+8 -10
net/sched/sch_dualpi2.c
··· 393 393 qdisc_qstats_overlimit(sch); 394 394 if (skb_in_l_queue(skb)) 395 395 qdisc_qstats_overlimit(q->l_queue); 396 - return qdisc_drop_reason(skb, sch, to_free, 397 - SKB_DROP_REASON_QDISC_OVERLIMIT); 396 + return qdisc_drop_reason(skb, sch, to_free, QDISC_DROP_OVERLIMIT); 398 397 } 399 398 400 399 if (q->drop_early && must_drop(sch, q, skb)) { 401 - qdisc_drop_reason(skb, sch, to_free, 402 - SKB_DROP_REASON_QDISC_CONGESTED); 400 + qdisc_drop_reason(skb, sch, to_free, QDISC_DROP_CONGESTED); 403 401 return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; 404 402 } 405 403 ··· 571 573 } 572 574 573 575 static void drop_and_retry(struct dualpi2_sched_data *q, struct sk_buff *skb, 574 - struct Qdisc *sch, enum skb_drop_reason reason) 576 + struct Qdisc *sch, enum qdisc_drop_reason reason) 575 577 { 576 578 ++q->deferred_drops_cnt; 577 579 q->deferred_drops_len += qdisc_pkt_len(skb); 578 - kfree_skb_reason(skb, reason); 580 + qdisc_dequeue_drop(sch, skb, reason); 579 581 qdisc_qstats_drop(sch); 580 582 } 581 583 ··· 590 592 591 593 while ((skb = dequeue_packet(sch, q, &credit_change, now))) { 592 594 if (!q->drop_early && must_drop(sch, q, skb)) { 593 - drop_and_retry(q, skb, sch, 594 - SKB_DROP_REASON_QDISC_CONGESTED); 595 + drop_and_retry(q, skb, sch, QDISC_DROP_CONGESTED); 595 596 continue; 596 597 } 597 598 598 599 if (skb_in_l_queue(skb) && do_step_aqm(q, skb, now)) { 599 600 qdisc_qstats_drop(q->l_queue); 600 - drop_and_retry(q, skb, sch, 601 - SKB_DROP_REASON_DUALPI2_STEP_DROP); 601 + drop_and_retry(q, skb, sch, QDISC_DROP_L4S_STEP_NON_ECN); 602 602 continue; 603 603 } 604 604 ··· 912 916 { 913 917 struct dualpi2_sched_data *q = qdisc_priv(sch); 914 918 int err; 919 + 920 + sch->flags |= TCQ_F_DEQUEUE_DROPS; 915 921 916 922 q->l_queue = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops, 917 923 TC_H_MAKE(sch->handle, 1), extack);
+3 -7
net/sched/sch_fq.c
··· 539 539 return unlikely((s64)skb->tstamp > (s64)(now + q->horizon)); 540 540 } 541 541 542 - #define FQDR(reason) SKB_DROP_REASON_FQ_##reason 543 - 544 542 static int fq_enqueue(struct sk_buff *skb, struct Qdisc *sch, 545 543 struct sk_buff **to_free) 546 544 { ··· 550 552 band = fq_prio2band(q->prio2band, skb->priority & TC_PRIO_MAX); 551 553 if (unlikely(q->band_pkt_count[band] >= sch->limit)) { 552 554 q->stat_band_drops[band]++; 553 - return qdisc_drop_reason(skb, sch, to_free, 554 - FQDR(BAND_LIMIT)); 555 + return qdisc_drop_reason(skb, sch, to_free, QDISC_DROP_BAND_LIMIT); 555 556 } 556 557 557 558 now = ktime_get_ns(); ··· 562 565 if (q->horizon_drop) { 563 566 q->stat_horizon_drops++; 564 567 return qdisc_drop_reason(skb, sch, to_free, 565 - FQDR(HORIZON_LIMIT)); 568 + QDISC_DROP_HORIZON_LIMIT); 566 569 } 567 570 q->stat_horizon_caps++; 568 571 skb->tstamp = now + q->horizon; ··· 576 579 if (unlikely(f->qlen >= q->flow_plimit)) { 577 580 q->stat_flows_plimit++; 578 581 return qdisc_drop_reason(skb, sch, to_free, 579 - FQDR(FLOW_LIMIT)); 582 + QDISC_DROP_FLOW_LIMIT); 580 583 } 581 584 582 585 if (fq_flow_is_detached(f)) { ··· 601 604 602 605 return NET_XMIT_SUCCESS; 603 606 } 604 - #undef FQDR 605 607 606 608 static void fq_check_throttled(struct fq_sched_data *q, u64 now) 607 609 {
+2 -2
net/sched/sch_fq_codel.c
··· 168 168 skb = dequeue_head(flow); 169 169 len += qdisc_pkt_len(skb); 170 170 mem += get_codel_cb(skb)->mem_usage; 171 - tcf_set_drop_reason(skb, SKB_DROP_REASON_QDISC_OVERLIMIT); 171 + tcf_set_qdisc_drop_reason(skb, QDISC_DROP_OVERLIMIT); 172 172 __qdisc_drop(skb, to_free); 173 173 } while (++i < max_packets && len < threshold); 174 174 ··· 275 275 { 276 276 struct Qdisc *sch = ctx; 277 277 278 - qdisc_dequeue_drop(sch, skb, SKB_DROP_REASON_QDISC_CONGESTED); 278 + qdisc_dequeue_drop(sch, skb, QDISC_DROP_CONGESTED); 279 279 qdisc_qstats_drop(sch); 280 280 } 281 281
+2 -2
net/sched/sch_fq_pie.c
··· 130 130 static int fq_pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, 131 131 struct sk_buff **to_free) 132 132 { 133 - enum skb_drop_reason reason = SKB_DROP_REASON_QDISC_OVERLIMIT; 133 + enum qdisc_drop_reason reason = QDISC_DROP_OVERLIMIT; 134 134 struct fq_pie_sched_data *q = qdisc_priv(sch); 135 135 struct fq_pie_flow *sel_flow; 136 136 int ret; ··· 162 162 q->overmemory++; 163 163 } 164 164 165 - reason = SKB_DROP_REASON_QDISC_CONGESTED; 165 + reason = QDISC_DROP_CONGESTED; 166 166 167 167 if (!pie_drop_early(sch, &q->p_params, &sel_flow->vars, 168 168 sel_flow->backlog, skb->len)) {
+27 -2
net/sched/sch_generic.c
··· 25 25 #include <linux/skb_array.h> 26 26 #include <linux/if_macvlan.h> 27 27 #include <linux/bpf.h> 28 + #include <trace/events/qdisc.h> 28 29 #include <net/sch_generic.h> 29 30 #include <net/pkt_sched.h> 30 31 #include <net/dst.h> 31 32 #include <net/hotdata.h> 32 - #include <trace/events/qdisc.h> 33 33 #include <trace/events/net.h> 34 34 #include <net/xfrm.h> 35 35 36 36 /* Qdisc to use by default */ 37 37 const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops; 38 38 EXPORT_SYMBOL(default_qdisc_ops); 39 + 40 + void __tcf_kfree_skb_list(struct sk_buff *skb, struct Qdisc *q, 41 + struct netdev_queue *txq, struct net_device *dev) 42 + { 43 + while (skb) { 44 + u32 reason = tc_skb_cb(skb)->drop_reason; 45 + struct sk_buff *next = skb->next; 46 + enum skb_drop_reason skb_reason; 47 + 48 + prefetch(next); 49 + /* TC classifier and qdisc share drop_reason storage. 50 + * Check subsystem mask to identify qdisc drop reasons, 51 + * else pass through skb_drop_reason set by TC classifier. 52 + */ 53 + if ((reason & SKB_DROP_REASON_SUBSYS_MASK) == __QDISC_DROP_REASON) { 54 + trace_qdisc_drop(q, txq, dev, skb, (enum qdisc_drop_reason)reason); 55 + skb_reason = SKB_DROP_REASON_QDISC_DROP; 56 + } else { 57 + skb_reason = (enum skb_drop_reason)reason; 58 + } 59 + kfree_skb_reason(skb, skb_reason); 60 + skb = next; 61 + } 62 + } 63 + EXPORT_SYMBOL(__tcf_kfree_skb_list); 39 64 40 65 static void qdisc_maybe_clear_missed(struct Qdisc *q, 41 66 const struct netdev_queue *txq) ··· 766 741 err = skb_array_produce(q, skb); 767 742 768 743 if (unlikely(err)) { 769 - tcf_set_drop_reason(skb, SKB_DROP_REASON_QDISC_OVERLIMIT); 744 + tcf_set_qdisc_drop_reason(skb, QDISC_DROP_OVERLIMIT); 770 745 771 746 if (qdisc_is_percpu_stats(qdisc)) 772 747 return qdisc_drop_cpu(skb, qdisc, to_free);
+2 -2
net/sched/sch_gred.c
··· 251 251 252 252 q->stats.pdrop++; 253 253 drop: 254 - return qdisc_drop_reason(skb, sch, to_free, SKB_DROP_REASON_QDISC_OVERLIMIT); 254 + return qdisc_drop_reason(skb, sch, to_free, QDISC_DROP_OVERLIMIT); 255 255 256 256 congestion_drop: 257 - qdisc_drop_reason(skb, sch, to_free, SKB_DROP_REASON_QDISC_CONGESTED); 257 + qdisc_drop_reason(skb, sch, to_free, QDISC_DROP_CONGESTED); 258 258 return NET_XMIT_CN; 259 259 } 260 260
+2 -2
net/sched/sch_pie.c
··· 85 85 static int pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, 86 86 struct sk_buff **to_free) 87 87 { 88 - enum skb_drop_reason reason = SKB_DROP_REASON_QDISC_OVERLIMIT; 88 + enum qdisc_drop_reason reason = QDISC_DROP_OVERLIMIT; 89 89 struct pie_sched_data *q = qdisc_priv(sch); 90 90 bool enqueue = false; 91 91 ··· 94 94 goto out; 95 95 } 96 96 97 - reason = SKB_DROP_REASON_QDISC_CONGESTED; 97 + reason = QDISC_DROP_CONGESTED; 98 98 99 99 if (!pie_drop_early(sch, &q->params, &q->vars, sch->qstats.backlog, 100 100 skb->len)) {
+2 -2
net/sched/sch_red.c
··· 70 70 static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch, 71 71 struct sk_buff **to_free) 72 72 { 73 - enum skb_drop_reason reason = SKB_DROP_REASON_QDISC_CONGESTED; 73 + enum qdisc_drop_reason reason = QDISC_DROP_CONGESTED; 74 74 struct red_sched_data *q = qdisc_priv(sch); 75 75 struct Qdisc *child = q->qdisc; 76 76 unsigned int len; ··· 108 108 break; 109 109 110 110 case RED_HARD_MARK: 111 - reason = SKB_DROP_REASON_QDISC_OVERLIMIT; 111 + reason = QDISC_DROP_OVERLIMIT; 112 112 qdisc_qstats_overlimit(sch); 113 113 if (red_use_harddrop(q) || !red_use_ecn(q)) { 114 114 q->stats.forced_drop++;
+2 -2
net/sched/sch_sfb.c
··· 280 280 struct sk_buff **to_free) 281 281 { 282 282 283 - enum skb_drop_reason reason = SKB_DROP_REASON_QDISC_OVERLIMIT; 283 + enum qdisc_drop_reason reason = QDISC_DROP_OVERLIMIT; 284 284 struct sfb_sched_data *q = qdisc_priv(sch); 285 285 unsigned int len = qdisc_pkt_len(skb); 286 286 struct Qdisc *child = q->qdisc; ··· 381 381 } 382 382 383 383 r = get_random_u16() & SFB_MAX_PROB; 384 - reason = SKB_DROP_REASON_QDISC_CONGESTED; 384 + reason = QDISC_DROP_CONGESTED; 385 385 386 386 if (unlikely(r < p_min)) { 387 387 if (unlikely(p_min > SFB_MAX_PROB / 2)) {
+4 -4
net/sched/sch_sfq.c
··· 302 302 sfq_dec(q, x); 303 303 sch->q.qlen--; 304 304 qdisc_qstats_backlog_dec(sch, skb); 305 - qdisc_drop(skb, sch, to_free); 305 + qdisc_drop_reason(skb, sch, to_free, QDISC_DROP_OVERLIMIT); 306 306 return len; 307 307 } 308 308 ··· 363 363 if (x == SFQ_EMPTY_SLOT) { 364 364 x = q->dep[0].next; /* get a free slot */ 365 365 if (x >= SFQ_MAX_FLOWS) 366 - return qdisc_drop(skb, sch, to_free); 366 + return qdisc_drop_reason(skb, sch, to_free, QDISC_DROP_MAXFLOWS); 367 367 q->ht[hash] = x; 368 368 slot = &q->slots[x]; 369 369 slot->hash = hash; ··· 420 420 if (slot->qlen >= q->maxdepth) { 421 421 congestion_drop: 422 422 if (!sfq_headdrop(q)) 423 - return qdisc_drop(skb, sch, to_free); 423 + return qdisc_drop_reason(skb, sch, to_free, QDISC_DROP_FLOW_LIMIT); 424 424 425 425 /* We know we have at least one packet in queue */ 426 426 head = slot_dequeue_head(slot); 427 427 delta = qdisc_pkt_len(head) - qdisc_pkt_len(skb); 428 428 sch->qstats.backlog -= delta; 429 429 slot->backlog -= delta; 430 - qdisc_drop(head, sch, to_free); 430 + qdisc_drop_reason(head, sch, to_free, QDISC_DROP_FLOW_LIMIT); 431 431 432 432 slot_queue_add(slot, skb); 433 433 qdisc_tree_reduce_backlog(sch, 0, delta);