drivers/infiniband/core/user_mad.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/core/user_mad.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/core/user_mad.c- Extension
.c- Size
- 37533 bytes
- Lines
- 1519
- Domain
- Driver Families
- Bucket
- drivers/infiniband
- Inferred role
- Driver Families: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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/module.hlinux/init.hlinux/device.hlinux/err.hlinux/fs.hlinux/cdev.hlinux/dma-mapping.hlinux/poll.hlinux/mutex.hlinux/kref.hlinux/compat.hlinux/sched.hlinux/semaphore.hlinux/slab.hlinux/nospec.hlinux/uaccess.hrdma/ib_mad.hrdma/ib_user_mad.hrdma/rdma_netlink.hcore_priv.htrace/events/ib_umad.h
Detected Declarations
struct ib_umad_portstruct ib_umad_devicestruct ib_umad_filestruct ib_umad_packetstruct ib_rmpp_mad_hdrfunction ib_umad_dev_freefunction ib_umad_dev_getfunction ib_umad_dev_putfunction hdr_sizefunction queue_packetfunction dequeue_sendfunction send_handlerfunction recv_handlerfunction copy_recv_madfunction copy_send_madfunction ib_umad_readfunction copy_rmpp_madfunction same_destinationfunction is_duplicatefunction ib_umad_writefunction ib_umad_pollfunction ib_umad_reg_agentfunction ib_umad_reg_agent2function ib_umad_unreg_agentfunction ib_umad_enable_pkeyfunction ib_umad_ioctlfunction ib_umad_compat_ioctlfunction ib_umad_openfunction ib_umad_closefunction list_for_each_entry_safefunction ib_umad_sm_openfunction ib_umad_sm_closefunction ib_umad_get_nl_infofunction ib_issm_get_nl_infofunction ibdev_showfunction port_showfunction abi_version_showfunction ib_umad_release_portfunction ib_umad_init_port_devfunction ib_umad_init_portfunction ib_umad_kill_portfunction list_for_each_entryfunction ib_umad_add_onefunction ib_umad_remove_onefunction rdma_for_each_portfunction ib_umad_initfunction ib_umad_cleanupmodule init ib_umad_init
Annotated Snippet
static const struct file_operations umad_fops = {
.owner = THIS_MODULE,
.read = ib_umad_read,
.write = ib_umad_write,
.poll = ib_umad_poll,
.unlocked_ioctl = ib_umad_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = ib_umad_compat_ioctl,
#endif
.open = ib_umad_open,
.release = ib_umad_close,
};
static int ib_umad_sm_open(struct inode *inode, struct file *filp)
{
struct ib_umad_port *port;
struct ib_port_modify props = {
.set_port_cap_mask = IB_PORT_SM
};
int ret;
port = container_of(inode->i_cdev, struct ib_umad_port, sm_cdev);
if (filp->f_flags & O_NONBLOCK) {
if (down_trylock(&port->sm_sem)) {
ret = -EAGAIN;
goto fail;
}
} else {
if (down_interruptible(&port->sm_sem)) {
ret = -ERESTARTSYS;
goto fail;
}
}
if (!rdma_dev_access_netns(port->ib_dev, current->nsproxy->net_ns)) {
ret = -EPERM;
goto err_up_sem;
}
ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
if (ret)
goto err_up_sem;
filp->private_data = port;
nonseekable_open(inode, filp);
return 0;
err_up_sem:
up(&port->sm_sem);
fail:
return ret;
}
static int ib_umad_sm_close(struct inode *inode, struct file *filp)
{
struct ib_umad_port *port = filp->private_data;
struct ib_port_modify props = {
.clr_port_cap_mask = IB_PORT_SM
};
int ret = 0;
mutex_lock(&port->file_mutex);
if (port->ib_dev)
ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props);
mutex_unlock(&port->file_mutex);
up(&port->sm_sem);
return ret;
}
static const struct file_operations umad_sm_fops = {
.owner = THIS_MODULE,
.open = ib_umad_sm_open,
.release = ib_umad_sm_close,
};
static struct ib_umad_port *get_port(struct ib_device *ibdev,
struct ib_umad_device *umad_dev,
u32 port)
{
if (!umad_dev)
return ERR_PTR(-EOPNOTSUPP);
if (!rdma_is_port_valid(ibdev, port))
return ERR_PTR(-EINVAL);
if (!rdma_cap_ib_mad(ibdev, port))
return ERR_PTR(-EOPNOTSUPP);
Annotation
- Immediate include surface: `linux/module.h`, `linux/init.h`, `linux/device.h`, `linux/err.h`, `linux/fs.h`, `linux/cdev.h`, `linux/dma-mapping.h`, `linux/poll.h`.
- Detected declarations: `struct ib_umad_port`, `struct ib_umad_device`, `struct ib_umad_file`, `struct ib_umad_packet`, `struct ib_rmpp_mad_hdr`, `function ib_umad_dev_free`, `function ib_umad_dev_get`, `function ib_umad_dev_put`, `function hdr_size`, `function queue_packet`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: pattern 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.