net/rxrpc/call_event.c

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

File Facts

System
Linux kernel
Corpus path
net/rxrpc/call_event.c
Extension
.c
Size
13233 bytes
Lines
498
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 (lost) {
			unsigned int ix = __ffs(lost);
			struct rxrpc_txbuf *txb = tq->bufs[ix];

			__clear_bit(ix, &lost);
			rxrpc_see_txbuf(txb, rxrpc_txbuf_see_lost);

			req.tq  = tq;
			req.seq = tq->qbase + ix;
			req.n   = 1;
			rxrpc_retransmit_data(call, &req);
		}
	}

	rxrpc_get_rto_backoff(call, req.did_send);
	_leave("");
}

/*
 * Resend the highest-seq DATA packet so far transmitted for RACK-TLP [RFC8985 7.3].
 */
void rxrpc_resend_tlp(struct rxrpc_call *call)
{
	struct rxrpc_send_data_req req = {
		.now		= ktime_get_real(),
		.seq		= call->tx_transmitted,
		.n		= 1,
		.tlp_probe	= true,
		.trace		= rxrpc_txdata_tlp_retransmit,
	};

	/* There's a chance it'll be on the tail segment of the queue. */
	req.tq = READ_ONCE(call->tx_qtail);
	if (req.tq &&
	    before(call->tx_transmitted, req.tq->qbase + RXRPC_NR_TXQUEUE)) {
		rxrpc_retransmit_data(call, &req);
		return;
	}

	for (req.tq = call->tx_queue; req.tq; req.tq = req.tq->next) {
		if (after_eq(call->tx_transmitted, req.tq->qbase) &&
		    before(call->tx_transmitted, req.tq->qbase + RXRPC_NR_TXQUEUE)) {
			rxrpc_retransmit_data(call, &req);
			return;
		}
	}
}

/*
 * Start transmitting the reply to a service.  This cancels the need to ACK the
 * request if we haven't yet done so.
 */
static void rxrpc_begin_service_reply(struct rxrpc_call *call)
{
	rxrpc_set_call_state(call, RXRPC_CALL_SERVER_SEND_REPLY);
	if (call->ackr_reason == RXRPC_ACK_DELAY)
		call->ackr_reason = 0;
	call->delay_ack_at = KTIME_MAX;
	trace_rxrpc_timer_can(call, rxrpc_timer_trace_delayed_ack);
}

/*
 * Close the transmission phase.  After this point there is no more data to be
 * transmitted in the call.
 */
static void rxrpc_close_tx_phase(struct rxrpc_call *call)
{
	_debug("________awaiting reply/ACK__________");

	switch (__rxrpc_call_state(call)) {
	case RXRPC_CALL_CLIENT_SEND_REQUEST:
		rxrpc_set_call_state(call, RXRPC_CALL_CLIENT_AWAIT_REPLY);
		break;
	case RXRPC_CALL_SERVER_SEND_REPLY:
		rxrpc_set_call_state(call, RXRPC_CALL_SERVER_AWAIT_ACK);
		break;
	default:
		break;
	}
}

/*
 * Transmit some as-yet untransmitted data, to a maximum of the supplied limit.
 */
static void rxrpc_transmit_fresh_data(struct rxrpc_call *call, unsigned int limit,
				      enum rxrpc_txdata_trace trace)
{
	int space = rxrpc_tx_window_space(call);

	if (!test_bit(RXRPC_CALL_EXPOSED, &call->flags)) {

Annotation

Implementation Notes