/* If there is still burst allowance left skip random early drop */ if (vars->burst_time > 0) returnfalse;
/* If current delay is less than half of target, and *ifdropprobislowalready,disableearly_drop
*/ if ((vars->qdelay < params->target / 2) &&
(vars->prob < MAX_PROB / 5)) returnfalse;
/* If we have fewer than 2 mtu-sized packets, disable pie_drop_early, *similartomin_thinRED
*/ if (backlog < 2 * mtu) returnfalse;
/* If bytemode is turned on, use packet size to compute new *probablity.Smallerpacketswillhavelowerdropprobinthiscase
*/ if (params->bytemode && packet_size <= mtu)
local_prob = (u64)packet_size * div_u64(local_prob, mtu); else
local_prob = vars->prob;
if (unlikely(qdisc_qlen(sch) >= sch->limit)) {
q->stats.overlimit++; goto out;
}
reason = SKB_DROP_REASON_QDISC_CONGESTED;
if (!pie_drop_early(sch, &q->params, &q->vars, sch->qstats.backlog,
skb->len)) {
enqueue = true;
} elseif (q->params.ecn && (q->vars.prob <= MAX_PROB / 10) &&
INET_ECN_set_ce(skb)) { /* If packet is ecn capable, mark it if drop probability *islowerthan10%,elsedropit.
*/
q->stats.ecn_mark++;
enqueue = true;
}
/* we can enqueue the packet */ if (enqueue) { /* Set enqueue time only when dq_rate_estimator is disabled. */ if (!q->params.dq_rate_estimator)
pie_set_enqueue_time(skb);
q->stats.packets_in++; if (qdisc_qlen(sch) > q->stats.maxq)
q->stats.maxq = qdisc_qlen(sch);
/* If dq_rate_estimator is disabled, calculate qdelay using the *packettimestamp.
*/ if (!params->dq_rate_estimator) {
vars->qdelay = now - pie_get_enqueue_time(skb);
if (vars->dq_tstamp != DTIME_INVALID)
dtime = now - vars->dq_tstamp;
vars->dq_tstamp = now;
if (backlog == 0)
vars->qdelay = 0;
if (dtime == 0) return;
goto burst_allowance_reduction;
}
/* If current queue is about 10 packets or more and dq_count is unset *wehaveenoughpacketstocalculatethedrainrate.Save *currenttimeasdq_tstampandstartmeasurementcycle.
*/ if (backlog >= QUEUE_THRESHOLD && vars->dq_count == DQCOUNT_INVALID) {
vars->dq_tstamp = psched_get_time();
vars->dq_count = 0;
}
/* Calculate the average drain rate from this value. If queue length *hasrecededtoasmallvalueviz.,<=QUEUE_THRESHOLDbytes,reset *thedq_countto-1aswedon'thaveenoughpacketstocalculatethe *drainrateanymore.Thefollowingifblockisenteredonlywhenwe *haveasubstantialqueuebuiltup(QUEUE_THRESHOLDbytesormore) *andwecalculatethedrainrateforthethresholdhere.dq_countis *inbytes,timedifferenceinpsched_time,hencerateisin *bytes/psched_time.
*/ if (vars->dq_count != DQCOUNT_INVALID) {
vars->dq_count += skb->len;
/* If the queue has receded below the threshold, we hold *ontothelastdrainratecalculated,elsewereset *dq_countto0tore-entertheifblockwhenthenext *packetisdequeued
*/ if (backlog < QUEUE_THRESHOLD) {
vars->dq_count = DQCOUNT_INVALID;
} else {
vars->dq_count = 0;
vars->dq_tstamp = psched_get_time();
}
goto burst_allowance_reduction;
}
}
return;
burst_allowance_reduction: if (vars->burst_time > 0) { if (vars->burst_time > dtime)
vars->burst_time -= dtime; else
vars->burst_time = 0;
}
}
EXPORT_SYMBOL_GPL(pie_process_dequeue);
void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars,
u32 backlog)
{
psched_time_t qdelay = 0; /* in pschedtime */
psched_time_t qdelay_old = 0; /* in pschedtime */
s64 delta = 0; /* determines the change in probability */
u64 oldprob;
u64 alpha, beta;
u32 power; bool update_prob = true;
if (params->dq_rate_estimator) {
qdelay_old = vars->qdelay;
vars->qdelay_old = vars->qdelay;
/* If qdelay is zero and backlog is not, it means backlog is very small, *sowedonotupdateprobabilityinthisround.
*/ if (qdelay == 0 && backlog != 0)
update_prob = false;
/* In the algorithm, alpha and beta are between 0 and 2 with typical *valueforalphaas0.125.Inthisimplementation,weusevalues0-32 *passedfromuserspacetorepresentthis.Also,alphaandbetahave *unitofHZandneedtobescaledbeforetheycanusedtoupdate *probability.alpha/betaareupdatedlocallybelowbyscalingdown *by16tocometo0-2range.
*/
alpha = ((u64)params->alpha * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
beta = ((u64)params->beta * (MAX_PROB / PSCHED_TICKS_PER_SEC)) >> 4;
/* We scale alpha and beta differently depending on how heavy the *congestionis.PleaseseeRFC8033fordetails.
*/ if (vars->prob < MAX_PROB / 10) {
alpha >>= 1;
beta >>= 1;
power = 100; while (vars->prob < div_u64(MAX_PROB, power) &&
power <= 1000000) {
alpha >>= 2;
beta >>= 2;
power *= 10;
}
}
/* alpha and beta should be between 0 and 32, in multiples of 1/16 */
delta += alpha * (qdelay - params->target);
delta += beta * (qdelay - qdelay_old);
oldprob = vars->prob;
/* to ensure we increase probability in steps of no more than 2% */ if (delta > (s64)(MAX_PROB / (100 / 2)) &&
vars->prob >= MAX_PROB / 10)
delta = (MAX_PROB / 100) * 2;
/* reset the timer to fire after 'tupdate'. tupdate is in jiffies. */ if (q->params.tupdate)
mod_timer(&q->adapt_timer, jiffies + q->params.tupdate);
spin_unlock(root_lock);
rcu_read_unlock();
}
/* avg_dq_rate is only valid if dq_rate_estimator is enabled */
st.dq_rate_estimating = q->params.dq_rate_estimator;
/* unscale and return dq_rate in bytes per sec */ if (q->params.dq_rate_estimator)
st.avg_dq_rate = q->vars.avg_dq_rate *
(PSCHED_TICKS_PER_SEC) >> PIE_SCALE;
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.