net/rxrpc/conn_object.c

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

File Facts

System
Linux kernel
Corpus path
net/rxrpc/conn_object.c
Extension
.c
Size
12865 bytes
Lines
496
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

switch (call->completion) {
		case RXRPC_CALL_SUCCEEDED:
			chan->last_seq = call->rx_highest_seq;
			chan->last_type = RXRPC_PACKET_TYPE_ACK;
			break;
		case RXRPC_CALL_LOCALLY_ABORTED:
			chan->last_abort = call->abort_code;
			chan->last_type = RXRPC_PACKET_TYPE_ABORT;
			break;
		default:
			chan->last_abort = RX_CALL_DEAD;
			chan->last_type = RXRPC_PACKET_TYPE_ABORT;
			break;
		}

		chan->last_call = chan->call_id;
		chan->call_id = chan->call_counter;
		chan->call = NULL;
	}

	_leave("");
}

/*
 * Disconnect a call and clear any channel it occupies when that call
 * terminates.
 */
void rxrpc_disconnect_call(struct rxrpc_call *call)
{
	struct rxrpc_connection *conn = call->conn;

	set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
	rxrpc_see_call(call, rxrpc_call_see_disconnected);

	call->peer->cong_ssthresh = call->cong_ssthresh;

	if (!hlist_unhashed(&call->error_link)) {
		spin_lock_irq(&call->peer->lock);
		hlist_del_init(&call->error_link);
		spin_unlock_irq(&call->peer->lock);
	}

	if (rxrpc_is_client_call(call)) {
		rxrpc_disconnect_client_call(call->bundle, call);
	} else {
		__rxrpc_disconnect_call(conn, call);
		conn->idle_timestamp = jiffies;
		if (atomic_dec_and_test(&conn->active))
			rxrpc_set_service_reap_timer(conn->rxnet,
						     jiffies + rxrpc_connection_expiry * HZ);
	}

	rxrpc_put_call(call, rxrpc_call_put_io_thread);
}

/*
 * Queue a connection's work processor, getting a ref to pass to the work
 * queue.
 */
void rxrpc_queue_conn(struct rxrpc_connection *conn, enum rxrpc_conn_trace why)
{
	if (atomic_read(&conn->active) >= 0 &&
	    rxrpc_queue_work(&conn->processor))
		rxrpc_see_connection(conn, why);
}

/*
 * Note the re-emergence of a connection.
 */
void rxrpc_see_connection(struct rxrpc_connection *conn,
			  enum rxrpc_conn_trace why)
{
	if (conn) {
		int r = refcount_read(&conn->ref);

		trace_rxrpc_conn(conn->debug_id, r, why);
	}
}

/*
 * Get a ref on a connection.
 */
struct rxrpc_connection *rxrpc_get_connection(struct rxrpc_connection *conn,
					      enum rxrpc_conn_trace why)
{
	int r;

	__refcount_inc(&conn->ref, &r);
	trace_rxrpc_conn(conn->debug_id, r + 1, why);
	return conn;

Annotation

Implementation Notes