net/rxrpc/sendmsg.c

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

File Facts

System
Linux kernel
Corpus path
net/rxrpc/sendmsg.c
Extension
.c
Size
22162 bytes
Lines
877
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration 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

switch (call->interruptibility) {
		case RXRPC_INTERRUPTIBLE:
		case RXRPC_PREINTERRUPTIBLE:
			set_current_state(TASK_INTERRUPTIBLE);
			break;
		case RXRPC_UNINTERRUPTIBLE:
		default:
			set_current_state(TASK_UNINTERRUPTIBLE);
			break;
		}

		if (rxrpc_call_state(call) != RXRPC_CALL_CLIENT_AWAIT_CONN)
			break;
		if ((call->interruptibility == RXRPC_INTERRUPTIBLE ||
		     call->interruptibility == RXRPC_PREINTERRUPTIBLE) &&
		    signal_pending(current)) {
			ret = sock_intr_errno(*timeo);
			break;
		}
		*timeo = schedule_timeout(*timeo);
	}

	remove_wait_queue(&call->waitq, &myself);
	__set_current_state(TASK_RUNNING);

no_wait:
	if (ret == 0 && rxrpc_call_is_complete(call))
		ret = call->error;

	_leave(" = %d", ret);
	return ret;
}

/*
 * Return true if there's sufficient Tx queue space.
 */
static bool rxrpc_check_tx_space(struct rxrpc_call *call, rxrpc_seq_t *_tx_win)
{
	rxrpc_seq_t tx_bottom = READ_ONCE(call->tx_bottom);

	if (_tx_win)
		*_tx_win = tx_bottom;
	return call->send_top - tx_bottom < 256;
}

/*
 * Wait for space to appear in the Tx queue or a signal to occur.
 */
static int rxrpc_wait_for_tx_window_intr(struct rxrpc_sock *rx,
					 struct rxrpc_call *call,
					 long *timeo)
{
	for (;;) {
		set_current_state(TASK_INTERRUPTIBLE);
		if (rxrpc_check_tx_space(call, NULL))
			return 0;

		if (rxrpc_call_is_complete(call))
			return call->error;

		if (signal_pending(current))
			return sock_intr_errno(*timeo);

		trace_rxrpc_txqueue(call, rxrpc_txqueue_wait);
		*timeo = schedule_timeout(*timeo);
	}
}

/*
 * Wait for space to appear in the Tx queue uninterruptibly, but with
 * a timeout of 2*RTT if no progress was made and a signal occurred.
 */
static int rxrpc_wait_for_tx_window_waitall(struct rxrpc_sock *rx,
					    struct rxrpc_call *call)
{
	rxrpc_seq_t tx_start, tx_win;
	signed long rtt, timeout;

	rtt = READ_ONCE(call->srtt_us) >> 3;
	rtt = usecs_to_jiffies(rtt) * 2;
	if (rtt < 2)
		rtt = 2;

	timeout = rtt;
	tx_start = READ_ONCE(call->tx_bottom);

	for (;;) {
		set_current_state(TASK_UNINTERRUPTIBLE);

		if (rxrpc_check_tx_space(call, &tx_win))

Annotation

Implementation Notes