FN(CANFD_RX_INVALID_FRAME) \
FN(CANXL_RX_INVALID_FRAME) \
FN(PFMEMALLOC) \
- FN(DUALPI2_STEP_DROP) \
FN(PSP_INPUT) \
FN(PSP_OUTPUT) \
FNe(MAX)
* reached a path or socket not eligible for use of memory reserves
*/
SKB_DROP_REASON_PFMEMALLOC,
- /**
- * @SKB_DROP_REASON_DUALPI2_STEP_DROP: dropped by the step drop
- * threshold of DualPI2 qdisc.
- */
- SKB_DROP_REASON_DUALPI2_STEP_DROP,
/** @SKB_DROP_REASON_PSP_INPUT: PSP input checks failed */
SKB_DROP_REASON_PSP_INPUT,
/** @SKB_DROP_REASON_PSP_OUTPUT: PSP output checks failed */
FN(BAND_LIMIT) \
FN(HORIZON_LIMIT) \
FN(FLOW_LIMIT) \
+ FN(L4S_STEP_NON_ECN) \
FNe(MAX)
#undef FN
* monopolizing queue resources.
*/
QDISC_DROP_FLOW_LIMIT,
+ /**
+ * @QDISC_DROP_L4S_STEP_NON_ECN: DualPI2 qdisc dropped a non-ECN-capable
+ * packet because the L4S queue delay exceeded the step threshold.
+ * Since the packet cannot be ECN-marked, it must be dropped to signal
+ * congestion. See RFC 9332 for the DualQ Coupled AQM step mechanism.
+ */
+ QDISC_DROP_L4S_STEP_NON_ECN,
/**
* @QDISC_DROP_MAX: the maximum of qdisc drop reasons, which
* shouldn't be used as a real 'reason' - only for tracing code gen
}
static void drop_and_retry(struct dualpi2_sched_data *q, struct sk_buff *skb,
- struct Qdisc *sch, enum skb_drop_reason reason)
+ struct Qdisc *sch, enum qdisc_drop_reason reason)
{
++q->deferred_drops_cnt;
q->deferred_drops_len += qdisc_pkt_len(skb);
- kfree_skb_reason(skb, reason);
+ qdisc_dequeue_drop(sch, skb, reason);
qdisc_qstats_drop(sch);
}
while ((skb = dequeue_packet(sch, q, &credit_change, now))) {
if (!q->drop_early && must_drop(sch, q, skb)) {
- drop_and_retry(q, skb, sch,
- SKB_DROP_REASON_QDISC_DROP);
+ drop_and_retry(q, skb, sch, QDISC_DROP_CONGESTED);
continue;
}
if (skb_in_l_queue(skb) && do_step_aqm(q, skb, now)) {
qdisc_qstats_drop(q->l_queue);
- drop_and_retry(q, skb, sch,
- SKB_DROP_REASON_DUALPI2_STEP_DROP);
+ drop_and_retry(q, skb, sch, QDISC_DROP_L4S_STEP_NON_ECN);
continue;
}
struct dualpi2_sched_data *q = qdisc_priv(sch);
int err;
+ sch->flags |= TCQ_F_DEQUEUE_DROPS;
+
q->l_queue = qdisc_create_dflt(sch->dev_queue, &pfifo_qdisc_ops,
TC_H_MAKE(sch->handle, 1), extack);
if (!q->l_queue)