drivers/nvme/host/rdma.c
Source file repositories/reference/linux-study-clean/drivers/nvme/host/rdma.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/nvme/host/rdma.c- Extension
.c- Size
- 64408 bytes
- Lines
- 2446
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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/module.hlinux/init.hlinux/slab.hrdma/mr_pool.hlinux/err.hlinux/string.hlinux/atomic.hlinux/blk-mq.hlinux/blk-integrity.hlinux/types.hlinux/list.hlinux/mutex.hlinux/scatterlist.hlinux/nvme.hlinux/unaligned.hrdma/ib_verbs.hrdma/rdma_cm.hlinux/nvme-rdma.hnvme.hfabrics.h
Detected Declarations
struct nvme_rdma_devicestruct nvme_rdma_qestruct nvme_rdma_sglstruct nvme_rdma_queuestruct nvme_rdma_requeststruct nvme_rdma_queuestruct nvme_rdma_ctrlenum nvme_rdma_queue_flagsfunction nvme_rdma_queue_idxfunction nvme_rdma_poll_queuefunction nvme_rdma_inline_data_sizefunction nvme_rdma_free_qefunction nvme_rdma_alloc_qefunction nvme_rdma_free_ringfunction nvme_rdma_qp_eventfunction nvme_rdma_wait_for_cmfunction nvme_rdma_create_qpfunction nvme_rdma_exit_requestfunction nvme_rdma_init_requestfunction nvme_rdma_init_hctxfunction nvme_rdma_init_admin_hctxfunction nvme_rdma_free_devfunction nvme_rdma_dev_putfunction nvme_rdma_dev_getfunction nvme_rdma_find_get_devicefunction nvme_rdma_free_cqfunction nvme_rdma_destroy_queue_ibfunction nvme_rdma_get_max_fr_pagesfunction nvme_rdma_create_cqfunction nvme_rdma_create_queue_ibfunction nvme_rdma_alloc_queuefunction __nvme_rdma_stop_queuefunction nvme_rdma_stop_queuefunction nvme_rdma_free_queuefunction nvme_rdma_free_io_queuesfunction nvme_rdma_stop_io_queuesfunction nvme_rdma_start_queuefunction nvme_rdma_start_io_queuesfunction nvme_rdma_alloc_io_queuesfunction nvme_rdma_alloc_tag_setfunction nvme_rdma_destroy_admin_queuefunction nvme_rdma_configure_admin_queuefunction nvme_rdma_configure_io_queuesfunction nvme_rdma_teardown_admin_queuefunction nvme_rdma_teardown_io_queuesfunction nvme_rdma_stop_ctrlfunction nvme_rdma_free_ctrlfunction nvme_rdma_reconnect_or_remove
Annotated Snippet
static const struct blk_mq_ops nvme_rdma_mq_ops;
static const struct blk_mq_ops nvme_rdma_admin_mq_ops;
static inline int nvme_rdma_queue_idx(struct nvme_rdma_queue *queue)
{
return queue - queue->ctrl->queues;
}
static bool nvme_rdma_poll_queue(struct nvme_rdma_queue *queue)
{
return nvme_rdma_queue_idx(queue) >
queue->ctrl->io_queues[HCTX_TYPE_DEFAULT] +
queue->ctrl->io_queues[HCTX_TYPE_READ];
}
static inline size_t nvme_rdma_inline_data_size(struct nvme_rdma_queue *queue)
{
return queue->cmnd_capsule_len - sizeof(struct nvme_command);
}
static void nvme_rdma_free_qe(struct ib_device *ibdev, struct nvme_rdma_qe *qe,
size_t capsule_size, enum dma_data_direction dir)
{
ib_dma_unmap_single(ibdev, qe->dma, capsule_size, dir);
kfree(qe->data);
}
static int nvme_rdma_alloc_qe(struct ib_device *ibdev, struct nvme_rdma_qe *qe,
size_t capsule_size, enum dma_data_direction dir)
{
qe->data = kzalloc(capsule_size, GFP_KERNEL);
if (!qe->data)
return -ENOMEM;
qe->dma = ib_dma_map_single(ibdev, qe->data, capsule_size, dir);
if (ib_dma_mapping_error(ibdev, qe->dma)) {
kfree(qe->data);
qe->data = NULL;
return -ENOMEM;
}
return 0;
}
static void nvme_rdma_free_ring(struct ib_device *ibdev,
struct nvme_rdma_qe *ring, size_t ib_queue_size,
size_t capsule_size, enum dma_data_direction dir)
{
int i;
for (i = 0; i < ib_queue_size; i++)
nvme_rdma_free_qe(ibdev, &ring[i], capsule_size, dir);
kfree(ring);
}
static struct nvme_rdma_qe *nvme_rdma_alloc_ring(struct ib_device *ibdev,
size_t ib_queue_size, size_t capsule_size,
enum dma_data_direction dir)
{
struct nvme_rdma_qe *ring;
int i;
ring = kzalloc_objs(struct nvme_rdma_qe, ib_queue_size);
if (!ring)
return NULL;
/*
* Bind the CQEs (post recv buffers) DMA mapping to the RDMA queue
* lifetime. It's safe, since any change in the underlying RDMA device
* will issue error recovery and queue re-creation.
*/
for (i = 0; i < ib_queue_size; i++) {
if (nvme_rdma_alloc_qe(ibdev, &ring[i], capsule_size, dir))
goto out_free_ring;
}
return ring;
out_free_ring:
nvme_rdma_free_ring(ibdev, ring, i, capsule_size, dir);
return NULL;
}
static void nvme_rdma_qp_event(struct ib_event *event, void *context)
{
pr_debug("QP event %s (%d)\n",
ib_event_msg(event->event), event->event);
}
Annotation
- Immediate include surface: `linux/module.h`, `linux/init.h`, `linux/slab.h`, `rdma/mr_pool.h`, `linux/err.h`, `linux/string.h`, `linux/atomic.h`, `linux/blk-mq.h`.
- Detected declarations: `struct nvme_rdma_device`, `struct nvme_rdma_qe`, `struct nvme_rdma_sgl`, `struct nvme_rdma_queue`, `struct nvme_rdma_request`, `struct nvme_rdma_queue`, `struct nvme_rdma_ctrl`, `enum nvme_rdma_queue_flags`, `function nvme_rdma_queue_idx`, `function nvme_rdma_poll_queue`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: pattern implementation candidate.
- 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.