net/rxrpc/input_rack.c

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

File Facts

System
Linux kernel
Corpus path
net/rxrpc/input_rack.c
Extension
.c
Size
12600 bytes
Lines
419
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

while (nacks) {
			unsigned int ix = __ffs(nacks);
			rxrpc_seq_t seq = tq->qbase + ix;
			ktime_t remaining;
			ktime_t xmit_ts = rxrpc_get_xmit_ts(tq, ix);

			__clear_bit(ix, &nacks);

			if (rxrpc_rack_sent_after(call->rack_xmit_ts, call->rack_end_seq,
						  xmit_ts, seq)) {
				remaining = ktime_sub(ktime_add(xmit_ts, lost_after), now);
				if (remaining <= 0) {
					rxrpc_rack_mark_lost(call, tq, ix);
					trace_rxrpc_rack_detect_loss(call, summary, seq);
				} else {
					timeout = max(remaining, timeout);
				}
			}
		}
	}

	return timeout;
}

/*
 * Detect losses and set a timer to retry the detection [RFC8958 6.2 Step 5].
 */
void rxrpc_rack_detect_loss_and_arm_timer(struct rxrpc_call *call,
					  struct rxrpc_ack_summary *summary)
{
	ktime_t timeout = rxrpc_rack_detect_loss(call, summary);

	if (timeout) {
		call->rack_timer_mode = RXRPC_CALL_RACKTIMER_RACK_REORDER;
		call->rack_timo_at = ktime_add(ktime_get_real(), timeout);
		trace_rxrpc_rack_timer(call, timeout, false);
		trace_rxrpc_timer_set(call, timeout, rxrpc_timer_trace_rack_reo);
	}
}

/*
 * Handle RACK-TLP RTO expiration [RFC8958 6.3].
 */
static void rxrpc_rack_mark_losses_on_rto(struct rxrpc_call *call)
{
	struct rxrpc_txqueue *tq;
	rxrpc_seq_t snd_una = call->acks_lowest_nak; /* Lowest unack'd seq */
	ktime_t lost_after = ktime_add(call->rack_rtt, call->rack_reo_wnd);
	ktime_t deadline = ktime_sub(ktime_get_real(), lost_after);

	for (tq = call->tx_queue; tq; tq = tq->next) {
		unsigned long unacked = ~tq->segment_acked;

		trace_rxrpc_rack_mark_loss_tq(call, tq);
		while (unacked) {
			unsigned int ix = __ffs(unacked);
			rxrpc_seq_t seq = tq->qbase + ix;
			ktime_t xmit_ts = rxrpc_get_xmit_ts(tq, ix);

			if (after(seq, call->tx_transmitted))
				return;
			__clear_bit(ix, &unacked);

			if (seq == snd_una ||
			    ktime_before(xmit_ts, deadline))
				rxrpc_rack_mark_lost(call, tq, ix);
		}
	}
}

/*
 * Calculate the TLP loss probe timeout (PTO) [RFC8958 7.2].
 */
ktime_t rxrpc_tlp_calc_pto(struct rxrpc_call *call, ktime_t now)
{
	unsigned int flight_size = rxrpc_tx_in_flight(call);
	ktime_t rto_at = ktime_add(call->tx_last_sent,
				   rxrpc_get_rto_backoff(call, false));
	ktime_t pto;

	if (call->rtt_count > 0) {
		/* Use 2*SRTT as the timeout. */
		pto = ns_to_ktime(call->srtt_us * NSEC_PER_USEC / 4);
		if (flight_size)
			pto = ktime_add(pto, call->tlp_max_ack_delay);
	} else {
		pto = NSEC_PER_SEC;
	}

	if (ktime_after(ktime_add(now, pto), rto_at))

Annotation

Implementation Notes