net/rds/rdma.c
Source file repositories/reference/linux-study-clean/net/rds/rdma.c
File Facts
- System
- Linux kernel
- Corpus path
net/rds/rdma.c- Extension
.c- Size
- 25606 bytes
- Lines
- 955
- 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.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- 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/pagemap.hlinux/slab.hlinux/rbtree.hlinux/dma-mapping.hrds.h
Detected Declarations
function Copyrightfunction rds_destroy_mrfunction __rds_put_mr_finalfunction rds_rdma_drop_keysfunction rds_pin_pagesfunction __rds_rdma_mapfunction PAGE_ALIGNfunction rds_get_mrfunction rds_get_mr_for_destfunction rds_free_mrfunction rds_rdma_unusefunction rds_rdma_free_opfunction rds_atomic_free_opfunction rds_rdma_pagesfunction rds_rdma_extra_sizefunction rds_cmsg_rdma_argsfunction destinationfunction rds_cmsg_rdma_mapfunction rds_cmsg_atomic
Annotated Snippet
if (!sg) {
ret = -ENOMEM;
goto out;
}
WARN_ON(!nents);
sg_init_table(sg, nents);
/* Stick all pages into the scatterlist */
for (i = 0 ; i < nents; i++)
sg_set_page(&sg[i], pages[i], PAGE_SIZE, 0);
rdsdebug("RDS: trans_private nents is %u\n", nents);
}
/* Obtain a transport specific MR. If this succeeds, the
* s/g list is now owned by the MR.
* Note that dma_map() implies that pending writes are
* flushed to RAM, so no dma_sync is needed here. */
trans_private = rs->rs_transport->get_mr(
sg, nents, rs, &mr->r_key, cp ? cp->cp_conn : NULL,
args->vec.addr, args->vec.bytes,
need_odp ? ODP_ZEROBASED : ODP_NOT_NEEDED);
if (IS_ERR(trans_private)) {
/* In ODP case, we don't GUP pages, so don't need
* to release anything.
*/
if (!need_odp) {
unpin_user_pages(pages, nr_pages);
kfree(sg);
}
ret = PTR_ERR(trans_private);
/* Trigger connection so that its ready for the next retry */
if (ret == -ENODEV && cp)
rds_conn_connect_if_down(cp->cp_conn);
goto out;
}
mr->r_trans_private = trans_private;
rdsdebug("RDS: get_mr put_user key is %x cookie_addr %p\n",
mr->r_key, (void *)(unsigned long) args->cookie_addr);
/* The user may pass us an unaligned address, but we can only
* map page aligned regions. So we keep the offset, and build
* a 64bit cookie containing <R_Key, offset> and pass that
* around. */
if (need_odp)
cookie = rds_rdma_make_cookie(mr->r_key, 0);
else
cookie = rds_rdma_make_cookie(mr->r_key,
args->vec.addr & ~PAGE_MASK);
if (cookie_ret)
*cookie_ret = cookie;
if (args->cookie_addr &&
put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) {
ret = -EFAULT;
goto out;
}
/* Inserting the new MR into the rbtree bumps its
* reference count. */
spin_lock_irqsave(&rs->rs_rdma_lock, flags);
found = rds_mr_tree_walk(&rs->rs_rdma_keys, mr->r_key, mr);
spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
BUG_ON(found && found != mr);
rdsdebug("RDS: get_mr key is %x\n", mr->r_key);
if (mr_ret) {
kref_get(&mr->r_kref);
*mr_ret = mr;
}
ret = 0;
out:
kfree(pages);
if (mr)
kref_put(&mr->r_kref, __rds_put_mr_final);
return ret;
}
int rds_get_mr(struct rds_sock *rs, sockptr_t optval, int optlen)
{
struct rds_get_mr_args args;
if (optlen != sizeof(struct rds_get_mr_args))
return -EINVAL;
if (copy_from_sockptr(&args, optval, sizeof(struct rds_get_mr_args)))
Annotation
- Immediate include surface: `linux/pagemap.h`, `linux/slab.h`, `linux/rbtree.h`, `linux/dma-mapping.h`, `rds.h`.
- Detected declarations: `function Copyright`, `function rds_destroy_mr`, `function __rds_put_mr_final`, `function rds_rdma_drop_keys`, `function rds_pin_pages`, `function __rds_rdma_map`, `function PAGE_ALIGN`, `function rds_get_mr`, `function rds_get_mr_for_dest`, `function rds_free_mr`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.