net/rds/connection.c
Source file repositories/reference/linux-study-clean/net/rds/connection.c
File Facts
- System
- Linux kernel
- Corpus path
net/rds/connection.c- Extension
.c- Size
- 28730 bytes
- Lines
- 1004
- 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.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kernel.hlinux/list.hlinux/slab.hlinux/export.hnet/ipv6.hnet/inet6_hashtables.hnet/addrconf.hrds.hloop.h
Detected Declarations
function hlist_for_each_entry_rcufunction rds_conn_path_resetfunction __rds_conn_path_initfunction ipv6_addr_equalfunction rds_conn_shutdownfunction rds_conn_path_destroyfunction rds_conn_destroyfunction __rds_inc_msg_cpfunction rds_conn_message_info_cmnfunction hlist_for_each_entry_rcufunction list_for_each_entryfunction rds_conn_message_infofunction rds6_conn_message_infofunction rds_conn_message_info_sendfunction rds6_conn_message_info_sendfunction rds_conn_message_info_retransfunction rds6_conn_message_info_retransfunction rds_for_each_conn_infofunction hlist_for_each_entry_rcufunction rds_walk_conn_path_infofunction hlist_for_each_entry_rcufunction rds_conn_info_visitorfunction rds6_conn_info_visitorfunction rds_conn_infofunction rds6_conn_infofunction rds_conn_initfunction rds_conn_exitfunction rds_conn_path_dropfunction rds_conn_dropfunction rds_conn_path_connect_if_downfunction rds_check_all_pathsfunction rds_conn_connect_if_downfunction __rds_conn_path_errorexport rds_conn_createexport rds_conn_create_outgoingexport rds_conn_destroyexport rds_for_each_conn_infoexport rds_conn_path_dropexport rds_conn_dropexport rds_conn_path_connect_if_downexport rds_conn_connect_if_down
Annotated Snippet
if (trans->t_prefer_loopback) {
if (likely(is_outgoing)) {
/* "outgoing" connection to local address.
* Protocol says it wants the connection
* handled by the loopback transport.
* This is what TCP does.
*/
trans = &rds_loop_transport;
} else {
/* No transport currently in use
* should end up here, but if it
* does, reset/destroy the connection.
*/
kfree(conn->c_path);
kmem_cache_free(rds_conn_slab, conn);
conn = ERR_PTR(-EOPNOTSUPP);
goto out;
}
}
}
conn->c_trans = trans;
init_waitqueue_head(&conn->c_hs_waitq);
for (i = 0; i < npaths; i++) {
__rds_conn_path_init(conn, &conn->c_path[i],
is_outgoing);
conn->c_path[i].cp_index = i;
conn->c_path[i].cp_wq =
alloc_ordered_workqueue("krds_cp_wq#%lu/%d", 0,
rds_conn_count, i);
if (!conn->c_path[i].cp_wq)
conn->c_path[i].cp_wq = rds_wq;
}
rcu_read_lock();
if (rds_destroy_pending(conn))
ret = -ENETDOWN;
else
ret = trans->conn_alloc(conn, GFP_ATOMIC);
if (ret) {
rcu_read_unlock();
free_cp = conn->c_path;
kmem_cache_free(rds_conn_slab, conn);
conn = ERR_PTR(ret);
goto out;
}
rdsdebug("allocated conn %p for %pI6c -> %pI6c over %s %s\n",
conn, laddr, faddr,
strnlen(trans->t_name, sizeof(trans->t_name)) ?
trans->t_name : "[unknown]", is_outgoing ? "(outgoing)" : "");
/*
* Since we ran without holding the conn lock, someone could
* have created the same conn (either normal or passive) in the
* interim. We check while holding the lock. If we won, we complete
* init and return our conn. If we lost, we rollback and return the
* other one.
*/
spin_lock_irqsave(&rds_conn_lock, flags);
if (parent) {
/* Creating passive conn */
if (parent->c_passive) {
trans->conn_free(conn->c_path[0].cp_transport_data);
free_cp = conn->c_path;
kmem_cache_free(rds_conn_slab, conn);
conn = parent->c_passive;
} else {
parent->c_passive = conn;
rds_cong_add_conn(conn);
rds_conn_count++;
}
} else {
/* Creating normal conn */
struct rds_connection *found;
found = rds_conn_lookup(net, head, laddr, faddr, trans,
tos, dev_if);
if (found) {
struct rds_conn_path *cp;
int i;
for (i = 0; i < npaths; i++) {
cp = &conn->c_path[i];
/* The ->conn_alloc invocation may have
* allocated resource for all paths, so all
* of them may have to be freed here.
*/
if (cp->cp_transport_data)
trans->conn_free(cp->cp_transport_data);
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/list.h`, `linux/slab.h`, `linux/export.h`, `net/ipv6.h`, `net/inet6_hashtables.h`, `net/addrconf.h`, `rds.h`.
- Detected declarations: `function hlist_for_each_entry_rcu`, `function rds_conn_path_reset`, `function __rds_conn_path_init`, `function ipv6_addr_equal`, `function rds_conn_shutdown`, `function rds_conn_path_destroy`, `function rds_conn_destroy`, `function __rds_inc_msg_cp`, `function rds_conn_message_info_cmn`, `function hlist_for_each_entry_rcu`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.