drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/infiniband/hw/vmw_pvrdma/pvrdma_cq.c- Extension
.c- Size
- 11213 bytes
- Lines
- 406
- Domain
- Driver Families
- Bucket
- drivers/infiniband
- Inferred role
- Driver Families: implementation source
- Status
- source 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.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
asm/page.hlinux/io.hlinux/wait.hrdma/ib_addr.hrdma/ib_smi.hrdma/ib_user_verbs.hrdma/uverbs_ioctl.hpvrdma.h
Detected Declarations
function pvrdma_req_notify_cqfunction pvrdma_create_cqfunction pvrdma_free_cqfunction pvrdma_destroy_cqfunction _pvrdma_flush_cqefunction pvrdma_poll_onefunction pvrdma_poll_cq
Annotated Snippet
if (IS_ERR(cq->umem)) {
ret = PTR_ERR(cq->umem);
goto err_cq;
}
npages = ib_umem_num_dma_blocks(cq->umem, PAGE_SIZE);
} else {
/* One extra page for shared ring state */
npages = 1 + (entries * sizeof(struct pvrdma_cqe) +
PAGE_SIZE - 1) / PAGE_SIZE;
/* Skip header page. */
cq->offset = PAGE_SIZE;
}
if (npages < 0 || npages > PVRDMA_PAGE_DIR_MAX_PAGES) {
dev_warn(&dev->pdev->dev,
"overflow pages in completion queue\n");
ret = -EINVAL;
goto err_umem;
}
ret = pvrdma_page_dir_init(dev, &cq->pdir, npages, cq->is_kernel);
if (ret) {
dev_warn(&dev->pdev->dev,
"could not allocate page directory\n");
goto err_umem;
}
/* Ring state is always the first page. Set in library for user cq. */
if (cq->is_kernel)
cq->ring_state = cq->pdir.pages[0];
else
pvrdma_page_dir_insert_umem(&cq->pdir, cq->umem, 0);
refcount_set(&cq->refcnt, 1);
init_completion(&cq->free);
spin_lock_init(&cq->cq_lock);
memset(cmd, 0, sizeof(*cmd));
cmd->hdr.cmd = PVRDMA_CMD_CREATE_CQ;
cmd->nchunks = npages;
cmd->ctx_handle = context ? context->ctx_handle : 0;
cmd->cqe = entries;
cmd->pdir_dma = cq->pdir.dir_dma;
ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_CREATE_CQ_RESP);
if (ret < 0) {
dev_warn(&dev->pdev->dev,
"could not create completion queue, error: %d\n", ret);
goto err_page_dir;
}
cq->ibcq.cqe = resp->cqe;
cq->cq_handle = resp->cq_handle;
cq_resp.cqn = resp->cq_handle;
spin_lock_irqsave(&dev->cq_tbl_lock, flags);
dev->cq_tbl[cq->cq_handle % dev->dsr->caps.max_cq] = cq;
spin_unlock_irqrestore(&dev->cq_tbl_lock, flags);
if (!cq->is_kernel) {
cq->uar = &context->uar;
/* Copy udata back. */
ret = ib_respond_udata(udata, cq_resp);
if (ret) {
pvrdma_destroy_cq(&cq->ibcq, udata);
return ret;
}
}
return 0;
err_page_dir:
pvrdma_page_dir_cleanup(dev, &cq->pdir);
err_umem:
ib_umem_release(cq->umem);
err_cq:
atomic_dec(&dev->num_cqs);
return ret;
}
static void pvrdma_free_cq(struct pvrdma_dev *dev, struct pvrdma_cq *cq)
{
if (refcount_dec_and_test(&cq->refcnt))
complete(&cq->free);
wait_for_completion(&cq->free);
ib_umem_release(cq->umem);
pvrdma_page_dir_cleanup(dev, &cq->pdir);
Annotation
- Immediate include surface: `asm/page.h`, `linux/io.h`, `linux/wait.h`, `rdma/ib_addr.h`, `rdma/ib_smi.h`, `rdma/ib_user_verbs.h`, `rdma/uverbs_ioctl.h`, `pvrdma.h`.
- Detected declarations: `function pvrdma_req_notify_cq`, `function pvrdma_create_cq`, `function pvrdma_free_cq`, `function pvrdma_destroy_cq`, `function _pvrdma_flush_cqe`, `function pvrdma_poll_one`, `function pvrdma_poll_cq`.
- Atlas domain: Driver Families / drivers/infiniband.
- Implementation status: source 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.