/* * Called to compute a smoothed rtt estimate. The data fed to this * routine either comes from timestamps, or from segments that were * known _not_ to have been retransmitted [see Karn/Partridge * Proceedings SIGCOMM 87]. The algorithm is from the SIGCOMM 88 * piece by Van Jacobson. * NOTE: the next three routines used to be one big routine. * To save cycles in the RFC 1323 implementation it was better to break * it up into three procedures. -- erics
*/ staticvoid rxrpc_rtt_estimator(struct rxrpc_call *call, long sample_rtt_us)
{ long m = sample_rtt_us; /* RTT */
u32 srtt = call->srtt_us;
/* The following amusing code comes from Jacobson's * article in SIGCOMM '88. Note that rtt and mdev * are scaled versions of rtt and mean deviation. * This is designed to be as fast as possible * m stands for "measurement". * * On a 1990 paper the rto value is changed to: * RTO = rtt + 4 * mdev * * Funny. This algorithm seems to be very broken. * These formulae increase RTO, when it should be decreased, increase * too slowly, when it should be increased quickly, decrease too quickly * etc. I guess in BSD RTO takes ONE value, so that it is absolutely * does not matter how to _calculate_ it. Seems, it was trap * that VJ failed to avoid. 8)
*/ if (srtt != 0) {
m -= (srtt >> 3); /* m is now error in rtt est */
srtt += m; /* rtt = 7/8 rtt + 1/8 new */ if (m < 0) {
m = -m; /* m is now abs(error) */
m -= (call->mdev_us >> 2); /* similar update on mdev */ /* This is similar to one of Eifel findings. * Eifel blocks mdev updates when rtt decreases. * This solution is a bit different: we use finer gain * for mdev in this case (alpha*beta). * Like Eifel it also prevents growth of rto, * but also it limits too fast rto decreases, * happening in pure Eifel.
*/ if (m > 0)
m >>= 3;
} else {
m -= (call->mdev_us >> 2); /* similar update on mdev */
}
call->mdev_us += m; /* mdev = 3/4 mdev + 1/4 new */ if (call->mdev_us > call->mdev_max_us) {
call->mdev_max_us = call->mdev_us; if (call->mdev_max_us > call->rttvar_us)
call->rttvar_us = call->mdev_max_us;
}
} else { /* no previous measure. */
srtt = m << 3; /* take the measured time to be rtt */
call->mdev_us = m << 1; /* make sure rto = 3*rtt */
call->rttvar_us = umax(call->mdev_us, rxrpc_rto_min_us(call));
call->mdev_max_us = call->rttvar_us;
}
call->srtt_us = umax(srtt, 1);
}
/* * Calculate rto without backoff. This is the second half of Van Jacobson's * routine referred to above.
*/ staticvoid rxrpc_set_rto(struct rxrpc_call *call)
{
u32 rto;
/* 1. If rtt variance happened to be less 50msec, it is hallucination. * It cannot be less due to utterly erratic ACK generation made * at least by solaris and freebsd. "Erratic ACKs" has _nothing_ * to do with delayed acks, because at cwnd>2 true delack timeout * is invisible. Actually, Linux-2.4 also generates erratic * ACKs in some circumstances.
*/
rto = __rxrpc_set_rto(call);
/* 2. Fixups made earlier cannot be right. * If we do not estimate RTO correctly without them, * all the algo is pure shit and should be replaced * with correct one. It is exactly, which we pretend to do.
*/
/* NOTE: clamping at RXRPC_RTO_MIN is not required, current algo * guarantees that rto is higher.
*/
call->rto_us = rxrpc_bound_rto(rto);
}
/* Only reset backoff on valid RTT measurement [RFC6298]. */
call->backoff = 0;
}
/* * Add RTT information to cache. This is called in softirq mode and has * exclusive access to the call RTT data.
*/ void rxrpc_call_add_rtt(struct rxrpc_call *call, enum rxrpc_rtt_rx_trace why, int rtt_slot,
rxrpc_serial_t send_serial, rxrpc_serial_t resp_serial,
ktime_t send_time, ktime_t resp_time)
{
s64 rtt_us;
rtt_us = ktime_to_us(ktime_sub(resp_time, send_time)); if (rtt_us < 0) return;
rxrpc_ack_update_rtt(call, resp_time, rtt_us); if (call->rtt_count < 3)
call->rtt_count++;
call->rtt_taken++;
/* * Get the retransmission timeout to set in nanoseconds, backing it off each * time we retransmit.
*/
ktime_t rxrpc_get_rto_backoff(struct rxrpc_call *call, bool retrans)
{
u64 timo_us;
u32 backoff = READ_ONCE(call->backoff);
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.