net/rds/message.c
Source file repositories/reference/linux-study-clean/net/rds/message.c
File Facts
- System
- Linux kernel
- Corpus path
net/rds/message.c- Extension
.c- Size
- 15004 bytes
- Lines
- 571
- 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.
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/slab.hlinux/export.hlinux/skbuff.hlinux/list.hlinux/errqueue.hrds.h
Detected Declarations
function rds_message_addreffunction rds_zcookie_addfunction rds_notify_msg_zcopy_purgefunction list_for_each_entry_safefunction rds_rm_zerocopy_callbackfunction dma_map_sgfunction rds_message_putfunction rds_message_populate_headerfunction rds_find_next_ext_spacefunction rds_message_add_extensionfunction rds_message_next_extensionfunction rds_message_add_rdma_dest_extensionfunction rds_message_zcopy_from_userfunction rds_message_copy_from_userfunction rds_message_inc_copy_to_userfunction rds_message_waitfunction rds_message_unmappedexport rds_message_addrefexport rds_message_putexport rds_message_populate_headerexport rds_message_add_extensionexport rds_message_add_rdma_dest_extensionexport rds_message_unmapped
Annotated Snippet
if (rds_zcookie_add(info, cookie)) {
spin_unlock_irqrestore(&q->lock, flags);
kfree(rds_info_from_znotifier(znotif));
/* caller invokes rds_wake_sk_sleep() */
return;
}
}
info = rds_info_from_znotifier(znotif);
ck = &info->zcookies;
memset(ck, 0, sizeof(*ck));
WARN_ON(!rds_zcookie_add(info, cookie));
list_add_tail(&info->rs_zcookie_next, &q->zcookie_head);
spin_unlock_irqrestore(&q->lock, flags);
/* caller invokes rds_wake_sk_sleep() */
}
/*
* This relies on dma_map_sg() not touching sg[].page during merging.
*/
static void rds_message_purge(struct rds_message *rm)
{
struct rds_znotifier *znotifier;
unsigned long i, flags;
bool zcopy;
if (unlikely(test_bit(RDS_MSG_PAGEVEC, &rm->m_flags)))
return;
spin_lock_irqsave(&rm->m_rs_lock, flags);
znotifier = rm->data.op_mmp_znotifier;
rm->data.op_mmp_znotifier = NULL;
zcopy = !!znotifier;
if (rm->m_rs) {
struct rds_sock *rs = rm->m_rs;
if (znotifier) {
rds_rm_zerocopy_callback(rs, znotifier);
rds_wake_sk_sleep(rs);
}
sock_put(rds_rs_to_sk(rs));
rm->m_rs = NULL;
} else if (znotifier) {
/*
* Zerocopy can fail before the message is queued on the
* socket, so there is no rs to carry the notification.
*/
mm_unaccount_pinned_pages(&znotifier->z_mmp);
kfree(rds_info_from_znotifier(znotifier));
}
spin_unlock_irqrestore(&rm->m_rs_lock, flags);
for (i = 0; i < rm->data.op_nents; i++) {
/* XXX will have to put_page for page refs */
if (!zcopy)
__free_page(sg_page(&rm->data.op_sg[i]));
else
put_page(sg_page(&rm->data.op_sg[i]));
}
rm->data.op_nents = 0;
if (rm->rdma.op_active)
rds_rdma_free_op(&rm->rdma);
if (rm->rdma.op_rdma_mr)
kref_put(&rm->rdma.op_rdma_mr->r_kref, __rds_put_mr_final);
if (rm->atomic.op_active)
rds_atomic_free_op(&rm->atomic);
if (rm->atomic.op_rdma_mr)
kref_put(&rm->atomic.op_rdma_mr->r_kref, __rds_put_mr_final);
}
void rds_message_put(struct rds_message *rm)
{
rdsdebug("put rm %p ref %d\n", rm, refcount_read(&rm->m_refcount));
WARN(!refcount_read(&rm->m_refcount), "danger refcount zero on %p\n", rm);
if (refcount_dec_and_test(&rm->m_refcount)) {
BUG_ON(!list_empty(&rm->m_sock_item));
BUG_ON(!list_empty(&rm->m_conn_item));
rds_message_purge(rm);
kfree(rm);
}
}
EXPORT_SYMBOL_GPL(rds_message_put);
void rds_message_populate_header(struct rds_header *hdr, __be16 sport,
__be16 dport, u64 seq)
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/slab.h`, `linux/export.h`, `linux/skbuff.h`, `linux/list.h`, `linux/errqueue.h`, `rds.h`.
- Detected declarations: `function rds_message_addref`, `function rds_zcookie_add`, `function rds_notify_msg_zcopy_purge`, `function list_for_each_entry_safe`, `function rds_rm_zerocopy_callback`, `function dma_map_sg`, `function rds_message_put`, `function rds_message_populate_header`, `function rds_find_next_ext_space`, `function rds_message_add_extension`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: integration 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.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.