/* The bandwidth estimator estimates the rate at which the network *cancurrentlydeliveroutbounddatapacketsforthisflow.Atahigh *level,itoperatesbytakingadeliveryratesampleforeachACK. * *Aratesamplerecordstherateatwhichthenetworkdeliveredpackets *forthisflow,calculatedoverthetimeintervalbetweenthetransmission *ofadatapacketandtheacknowledgmentofthatpacket. * *Specifically,overtheintervalbetweeneachtransmitandcorrespondingACK, *theestimatorgeneratesadeliveryratesample.Typicallyitusestherate *atwhichpacketswereacknowledged.However,theapproachofusingonlythe *acknowledgmentratefacesachallengeundertheprevalentACKdecimationor *compression:packetscantemporarilyappeartobedeliveredmuchquicker *thanthebottleneckrate.Sinceitisphysicallyimpossibletodothatina *sustainedfashion,whentheestimatornoticesthattheACKrateisfaster *thanthetransmitrate,itusesthelatter: * *send_rate=#pkts_delivered/(last_snd_time-first_snd_time) *ack_rate=#pkts_delivered/(last_ack_time-first_ack_time) *bw=min(send_rate,ack_rate) * *Noticetheestimatoressentiallyestimatesthegoodput,notalwaysthe *networkbottlenecklinkratewhenthesendingorreceivingislimitedby *otherfactorslikeapplicationsorreceiverwindowlimits.Theestimator *deliberatelyavoidsusingtheinter-packetspacingapproachbecausethat *approachrequiresalargenumberofsamplesandsophisticatedfiltering. * *TCPflowscanoftenbeapplication-limitedinrequest/responseworkloads. *Theestimatormarksabandwidthsampleasapplication-limitedifthere *wassomemomentduringthesampledwindowofpacketswhentherewasnodata *readytosendinthewritequeue.
*/
/* Snapshot the current delivery information in the skb, to generate *aratesamplelaterwhentheskbis(s)ackedintcp_rate_skb_delivered().
*/ void tcp_rate_skb_sent(struct sock *sk, struct sk_buff *skb)
{ struct tcp_sock *tp = tcp_sk(sk);
/* In general we need to start delivery rate samples from the *timewereceivedthemostrecentACK,toensureweinclude *thefulltimethenetworkneedstodeliverallin-flight *packets.Iftherearenopacketsinflightyet,thenwe *knowthatanyACKsafternowindicatethatthenetworkwas *abletodeliverthosepacketscompletelyinthesampling *intervalbetweennowandthenextACK. * *Notethatweusepackets_outinsteadoftcp_packets_in_flight(tp) *becausethelatterisaguessbasedonRTOandloss-marking *heuristics.Wedon'twantspuriousRTOsorlossmarkingstocause *aspuriouslysmalltimeinterval,causingaspuriouslyhigh *bandwidthestimate.
*/ if (!tp->packets_out) {
u64 tstamp_us = tcp_skb_timestamp_us(skb);
/* When an skb is sacked or acked, we fill in the rate sample with the (prior) *deliveryinformationwhentheskbwaslasttransmitted. * *IfanACK(s)acksmultipleskbs(e.g.,stretched-acks),thisfunctionis *calledmultipletimes.Wefavortheinformationfromthemostrecently *sentskb,i.e.,theskbwiththemostrecentlysenttimeandthehighest *sequence.
*/ void tcp_rate_skb_delivered(struct sock *sk, struct sk_buff *skb, struct rate_sample *rs)
{ struct tcp_sock *tp = tcp_sk(sk); struct tcp_skb_cb *scb = TCP_SKB_CB(skb);
u64 tx_tstamp;
/* Record send time of most recently ACKed packet: */
tp->first_tx_mstamp = tx_tstamp; /* Find the duration of the "send phase" of this window: */
rs->interval_us = tcp_stamp_us_delta(tp->first_tx_mstamp,
scb->tx.first_tx_mstamp);
} /* Mark off the skb delivered once it's sacked to avoid being *usedagainwhenit'scumulativelyacked.Forackedpackets *wedon'tneedtoresetsinceit'llbefreedsoon.
*/ if (scb->sacked & TCPCB_SACKED_ACKED)
scb->tx.delivered_mstamp = 0;
}
/* Update the connection delivery information and generate a rate sample. */ void tcp_rate_gen(struct sock *sk, u32 delivered, u32 lost, bool is_sack_reneg, struct rate_sample *rs)
{ struct tcp_sock *tp = tcp_sk(sk);
u32 snd_us, ack_us;
/* Clear app limited if bubble is acked and gone. */ if (tp->app_limited && after(tp->delivered, tp->app_limited))
tp->app_limited = 0;
/* TODO: there are multiple places throughout tcp_ack() to get *currenttime.Refactorthecodeusinganew"tcp_acktag_state" *tocarrycurrenttime,flags,statslike"tcp_sacktag_state".
*/ if (delivered)
tp->delivered_mstamp = tp->tcp_mstamp;
rs->acked_sacked = delivered; /* freshly ACKed or SACKed */
rs->losses = lost; /* freshly marked lost */ /* Return an invalid sample if no timing information is available or *inrecoveryfromlosswithSACKreneging.Ratesamplestakenduring *aSACKrenegingeventmayoverestimatebwbyincludingpacketsthat *wereSACKedbeforethereneg.
*/ if (!rs->prior_mstamp || is_sack_reneg) {
rs->delivered = -1;
rs->interval_us = -1; return;
}
rs->delivered = tp->delivered - rs->prior_delivered;
rs->delivered_ce = tp->delivered_ce - rs->prior_delivered_ce; /* delivered_ce occupies less than 32 bits in the skb control block */
rs->delivered_ce &= TCPCB_DELIVERED_CE_MASK;
/* Model sending data and receiving ACKs as separate pipeline phases *forawindow.UsuallytheACKphaseislonger,butwithACK *compressionthesendphasecanbelonger.Tobesafeweusethe *longerphase.
*/
snd_us = rs->interval_us; /* send phase */
ack_us = tcp_stamp_us_delta(tp->tcp_mstamp,
rs->prior_mstamp); /* ack phase */
rs->interval_us = max(snd_us, ack_us);
/* Record both segment send and ack receive intervals */
rs->snd_interval_us = snd_us;
rs->rcv_interval_us = ack_us;
/* Record the last non-app-limited or the highest app-limited bw */ if (!rs->is_app_limited ||
((u64)rs->delivered * tp->rate_interval_us >=
(u64)tp->rate_delivered * rs->interval_us)) {
tp->rate_delivered = rs->delivered;
tp->rate_interval_us = rs->interval_us;
tp->rate_app_limited = rs->is_app_limited;
}
}
/* If a gap is detected between sends, mark the socket application-limited. */ void tcp_rate_check_app_limited(struct sock *sk)
{ struct tcp_sock *tp = tcp_sk(sk);
if (/* We have less than one packet to send. */
tp->write_seq - tp->snd_nxt < tp->mss_cache && /* Nothing in sending host's qdisc queues or NIC tx queue. */
sk_wmem_alloc_get(sk) < SKB_TRUESIZE(1) && /* We are not limited by CWND. */
tcp_packets_in_flight(tp) < tcp_snd_cwnd(tp) && /* All lost packets have been retransmitted. */
tp->lost_out <= tp->retrans_out)
tp->app_limited =
(tp->delivered + tcp_packets_in_flight(tp)) ? : 1;
}
EXPORT_SYMBOL_GPL(tcp_rate_check_app_limited);
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet am 2026-09-29)
¤
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.