drivers/infiniband/sw/rdmavt/mcast.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/sw/rdmavt/mcast.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/sw/rdmavt/mcast.c- Extension
.c- Size
- 8728 bytes
- Lines
- 401
- Domain
- Driver Families
- Bucket
- drivers/infiniband
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- 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/slab.hlinux/sched.hlinux/rculist.hrdma/rdma_vt.hrdma/rdmavt_qp.hmcast.h
Detected Declarations
function Copyrightfunction rvt_mcast_qp_freefunction rvt_mcast_freefunction rvt_mcast_addfunction list_for_each_entry_rcufunction rvt_attach_mcastfunction rvt_detach_mcastfunction rvt_mcast_tree_emptyexport rvt_mcast_find
Annotated Snippet
if (ret < 0) {
n = n->rb_left;
} else if (ret > 0) {
n = n->rb_right;
} else {
/* MGID/MLID must match */
if (mcast->mcast_addr.lid == lid) {
atomic_inc(&mcast->refcount);
found = mcast;
}
break;
}
}
spin_unlock_irqrestore(&ibp->lock, flags);
return found;
}
EXPORT_SYMBOL(rvt_mcast_find);
/*
* rvt_mcast_add - insert mcast GID into table and attach QP struct
* @mcast: the mcast GID table
* @mqp: the QP to attach
*
* Return: zero if both were added. Return EEXIST if the GID was already in
* the table but the QP was added. Return ESRCH if the QP was already
* attached and neither structure was added. Return EINVAL if the MGID was
* found, but the MLID did NOT match.
*/
static int rvt_mcast_add(struct rvt_dev_info *rdi, struct rvt_ibport *ibp,
struct rvt_mcast *mcast, struct rvt_mcast_qp *mqp)
{
struct rb_node **n = &ibp->mcast_tree.rb_node;
struct rb_node *pn = NULL;
int ret;
spin_lock_irq(&ibp->lock);
while (*n) {
struct rvt_mcast *tmcast;
struct rvt_mcast_qp *p;
pn = *n;
tmcast = rb_entry(pn, struct rvt_mcast, rb_node);
ret = memcmp(mcast->mcast_addr.mgid.raw,
tmcast->mcast_addr.mgid.raw,
sizeof(mcast->mcast_addr.mgid));
if (ret < 0) {
n = &pn->rb_left;
continue;
}
if (ret > 0) {
n = &pn->rb_right;
continue;
}
if (tmcast->mcast_addr.lid != mcast->mcast_addr.lid) {
ret = EINVAL;
goto bail;
}
/* Search the QP list to see if this is already there. */
list_for_each_entry_rcu(p, &tmcast->qp_list, list) {
if (p->qp == mqp->qp) {
ret = ESRCH;
goto bail;
}
}
if (tmcast->n_attached ==
rdi->dparms.props.max_mcast_qp_attach) {
ret = ENOMEM;
goto bail;
}
tmcast->n_attached++;
list_add_tail_rcu(&mqp->list, &tmcast->qp_list);
ret = EEXIST;
goto bail;
}
spin_lock(&rdi->n_mcast_grps_lock);
if (rdi->n_mcast_grps_allocated == rdi->dparms.props.max_mcast_grp) {
spin_unlock(&rdi->n_mcast_grps_lock);
ret = ENOMEM;
goto bail;
}
rdi->n_mcast_grps_allocated++;
spin_unlock(&rdi->n_mcast_grps_lock);
Annotation
- Immediate include surface: `linux/slab.h`, `linux/sched.h`, `linux/rculist.h`, `rdma/rdma_vt.h`, `rdma/rdmavt_qp.h`, `mcast.h`.
- Detected declarations: `function Copyright`, `function rvt_mcast_qp_free`, `function rvt_mcast_free`, `function rvt_mcast_add`, `function list_for_each_entry_rcu`, `function rvt_attach_mcast`, `function rvt_detach_mcast`, `function rvt_mcast_tree_empty`, `export rvt_mcast_find`.
- Atlas domain: Driver Families / drivers/infiniband.
- 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.