net/rxrpc/rtt.c

Source file repositories/reference/linux-study-clean/net/rxrpc/rtt.c

File Facts

System
Linux kernel
Corpus path
net/rxrpc/rtt.c
Extension
.c
Size
6412 bytes
Lines
209
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

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.
 */
static void 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);
}

static void rxrpc_update_rtt_min(struct rxrpc_call *call, ktime_t resp_time, long rtt_us)
{
	/* Window size 5mins in approx usec (ipv4.sysctl_tcp_min_rtt_wlen) */
	u32 wlen_us = 5ULL * NSEC_PER_SEC / 1024;

	minmax_running_min(&call->min_rtt, wlen_us, resp_time / 1024,
			   (u32)rtt_us ? : jiffies_to_usecs(1));
}

static void rxrpc_ack_update_rtt(struct rxrpc_call *call, ktime_t resp_time, long rtt_us)
{
	if (rtt_us < 0)
		return;

	/* Update RACK min RTT [RFC8985 6.1 Step 1]. */
	rxrpc_update_rtt_min(call, resp_time, rtt_us);

	rxrpc_rtt_estimator(call, rtt_us);
	rxrpc_set_rto(call);

	/* 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.

Annotation

Implementation Notes