/* 32b enable to support flows with windows up to ~8.6 * 1e9 packets *i.e.,twicethemaximalsnd_cwnd. *MAX_PROBmustbeconsistentwiththeRNGindualpi2_roll().
*/ #define MAX_PROB U32_MAX
/* alpha/beta values exchanged over netlink are in units of 256ns */ #define ALPHA_BETA_SHIFT 8
/* Scaled values of alpha/beta must fit in 32b to avoid overflow in later *computations.Consequently(seeanddualpi2_scale_alpha_beta()),their *netlink-providedvaluescanuseatmost31b,i.e.beatmost(2^23)-1 *(~4MHz)asthosearegivenin1/256th.Thisenabletotunealpha/betato *controlflowswhosemaximalRTTscanbeinusecuptofewsecs.
*/ #define ALPHA_BETA_MAX ((1U << 31) - 1)
/* Internal alpha/beta are in units of 64ns. *Thisenablestouseallalpha/betavaluesintheallowedrangewithoutloss *ofprecisionduetoroundingwhenscalingtheminternally,e.g., *scale_alpha_beta(1)willnotrounddownto0.
*/ #define ALPHA_BETA_GRANULARITY 6
/* PI2 parameters */
u64 pi2_target; /* Target delay in nanoseconds */
u32 pi2_tupdate; /* Timer frequency in nanoseconds */
u32 pi2_prob; /* Base PI probability */
u32 pi2_alpha; /* Gain factor for the integral rate response */
u32 pi2_beta; /* Gain factor for the proportional response */ struct hrtimer pi2_timer; /* prob update timer */
/* Step AQM (L-queue only) parameters */
u32 step_thresh; /* Step threshold */ bool step_in_packets; /* Step thresh in packets (1) or time (0) */
/* C-queue starvation protection */
s32 c_protection_credit; /* Credit (sign indicates which queue) */
s32 c_protection_init; /* Reset value of the credit */
u8 c_protection_wc; /* C-queue weight (between 0 and MAX_WC) */
u8 c_protection_wl; /* L-queue weight (MAX_WC - wc) */
/* General dualQ parameters */
u32 memory_limit; /* Memory limit of both queues */
u8 coupling_factor;/* Coupling factor (k) between both queues */
u8 ecn_mask; /* Mask to match packets into L-queue */
u32 min_qlen_step; /* Minimum queue length to apply step thresh */ bool drop_early; /* Drop at enqueue (1) instead of dequeue (0) */ bool drop_overload; /* Drop (1) on overload, or overflow (0) */ bool split_gso; /* Split aggregated skb (1) or leave as is (0) */
/* Statistics */
u64 c_head_ts; /* Enqueue timestamp of the C-queue head */
u64 l_head_ts; /* Enqueue timestamp of the L-queue head */
u64 last_qdelay; /* Q delay val at the last probability update */
u32 packets_in_c; /* Enqueue packet counter of the C-queue */
u32 packets_in_l; /* Enqueue packet counter of the L-queue */
u32 maxq; /* Maximum queue size of the C-queue */
u32 ecn_mark; /* ECN mark pkt counter due to PI probability */
u32 step_marks; /* ECN mark pkt counter due to step AQM */
u32 memory_used; /* Memory used of both queues */
u32 max_memory_used;/* Maximum used memory */
/* Packets in the C-queue are subject to a marking probability pC, which is the *squareoftheinternalPIprobability(i.e.,haveanoveralllowermark/drop *probability).Iftheqdiscisoverloaded,ignoreECTvaluesandonlydrop. * *NotethatthismarkingschemeisalsoappliedtoL4Spacketsduringoverload. *ReturntrueifpacketdroppingisrequiredinCqueue
*/ staticbool dualpi2_classic_marking(struct dualpi2_sched_data *q, struct sk_buff *skb, u32 prob, bool overload)
{ if (dualpi2_roll(prob) && dualpi2_roll(prob)) { if (overload || dualpi2_skb_cb(skb)->ect == INET_ECN_NOT_ECT) returntrue;
dualpi2_mark(q, skb);
} returnfalse;
}
/* Packets in the L-queue are subject to a marking probability pL given by the *internalPIprobabilityscaledbythecouplingfactor. * *Onoverload(i.e.,@local_l_probis>=100%): *-iftheqdiscisconfiguredtotradelossestopreservelatency(i.e., *@q->drop_overload),applyclassicdropsfirstbeforemarking. *-otherwise,preservethe"noloss"propertyofECNatthecostofqueueing *delay,eventuallyresultingintaildropbehavioroncesch->limitis *reached. *ReturntrueifpacketdroppingisrequiredinLqueue
*/ staticbool dualpi2_scalable_marking(struct dualpi2_sched_data *q, struct sk_buff *skb,
u64 local_l_prob, u32 prob, bool overload)
{ if (overload) { /* Apply classic drop */ if (!q->drop_overload ||
!(dualpi2_roll(prob) && dualpi2_roll(prob))) goto mark; returntrue;
}
/* We can safely cut the upper 32b as overload==false */ if (dualpi2_roll(local_l_prob)) { /* Non-ECT packets could have classified as L4S by filters. */ if (dualpi2_skb_cb(skb)->ect == INET_ECN_NOT_ECT) returntrue;
mark:
dualpi2_mark(q, skb);
} returnfalse;
}
/* Decide whether a given packet must be dropped (or marked if ECT), according *tothePI2probability. * *Nevermark/dropifwehaveastandingqueueoflessthan2MTUs.
*/ staticbool must_drop(struct Qdisc *sch, struct dualpi2_sched_data *q, struct sk_buff *skb)
{
u64 local_l_prob; bool overload;
u32 prob;
if (sch->qstats.backlog < 2 * psched_mtu(qdisc_dev(sch))) returnfalse;
/* By default, dualpi2 will split GSO skbs into independent skbs and enqueue *eachofthoseindividually.Thisyieldsthefollowingbenefits,atthe *expenseofCPUusage: *-Finer-grainedAQMactionsasthesub-packetsofaburstnolongersharethe *samefate(e.g.,therandommark/dropprobabilityisappliedindividually) *-Improvedprecisionofthestarvationprotection/WRRscheduleratdequeue, *asthesizeofthedequeuedpacketswillbesmaller.
*/ staticint dualpi2_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)
{ struct dualpi2_sched_data *q = qdisc_priv(sch); int err;
err = dualpi2_skb_classify(q, skb); if (err != NET_XMIT_SUCCESS) { if (err & __NET_XMIT_BYPASS)
qdisc_qstats_drop(sch);
__qdisc_drop(skb, to_free); return err;
}
if (q->split_gso && skb_is_gso(skb)) {
netdev_features_t features; struct sk_buff *nskb, *next; int cnt, byte_len, orig_len; int err;
features = netif_skb_features(skb);
nskb = skb_gso_segment(skb, features & ~NETIF_F_GSO_MASK); if (IS_ERR_OR_NULL(nskb)) return qdisc_drop(skb, sch, to_free);
/* Iterate through GSO fragments of an skb: *(1)Setpkt_lenfromthesingleGSOfragments *(2)Copyclassifiedandectvaluesofanskb *(3)Enqueuefragment&settsindualpi2_enqueue_skb
*/
qdisc_skb_cb(nskb)->pkt_len = nskb->len;
dualpi2_skb_cb(nskb)->classified =
dualpi2_skb_cb(skb)->classified;
dualpi2_skb_cb(nskb)->ect = dualpi2_skb_cb(skb)->ect;
err = dualpi2_enqueue_skb(nskb, sch, to_free);
if (err == NET_XMIT_SUCCESS) { /* Compute the backlog adjustment that needs *tobepropagatedintheqdisctreetoreflect *allnewskbssuccessfullyenqueued.
*/
++cnt;
byte_len += nskb->len;
}
} if (cnt > 1) { /* The caller will add the original skb stats to its *backlog,compensatethisifanynskbisenqueued.
*/
--cnt;
byte_len -= orig_len;
}
qdisc_tree_reduce_backlog(sch, -cnt, -byte_len);
consume_skb(skb); return err;
} return dualpi2_enqueue_skb(skb, sch, to_free);
}
/* Select the queue from which the next packet can be dequeued, ensuring that *neitherqueuecanstarvetheotherwithaWRRscheduler. * *ThesignoftheWRRcreditdeterminesthenextqueue,whilethesizeof *thedequeuedpacketdeterminesthemagnitudeoftheWRRcreditchange.If *eitherqueueisempty,theWRRcreditiskeptunchanged. * *Asthedequeuedpacketcanbedroppedlater,thecallerhastoperformthe *qdisc_bstats_update()calls.
*/ staticstruct sk_buff *dequeue_packet(struct Qdisc *sch, struct dualpi2_sched_data *q, int *credit_change,
u64 now)
{ struct sk_buff *skb = NULL; int c_len;
/* Alpha and beta take at most 32b, i.e, the delay difference would *overflowforqueuingdelaydifferences>~4.2sec.
*/
delta = ((s64)qdelay - (s64)q->pi2_target) * q->pi2_alpha;
delta += ((s64)qdelay - (s64)q->last_qdelay) * q->pi2_beta;
q->last_qdelay = qdelay;
/* Bound new_prob between 0 and MAX_PROB */ if (delta > 0) {
new_prob = __scale_delta(delta) + q->pi2_prob; if (new_prob < q->pi2_prob)
new_prob = MAX_PROB;
} else {
new_prob = q->pi2_prob - __scale_delta(~delta + 1); if (new_prob > q->pi2_prob)
new_prob = 0;
}
/* If we do not drop on overload, ensure we cap the L4S probability to *100%tokeepwindowfairnesswhenoverflowing.
*/ if (!q->drop_overload) return min_t(u32, new_prob, MAX_PROB / q->coupling_factor); return new_prob;
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.23Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-28)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.