drivers/infiniband/hw/mana/cq.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/mana/cq.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/mana/cq.c
Extension
.c
Size
9100 bytes
Lines
339
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (err) {
			ibdev_dbg(ibdev, "Failed to create queue for create cq, %d\n", err);
			return err;
		}

		mana_ucontext = rdma_udata_to_drv_context(udata, struct mana_ib_ucontext,
							  ibucontext);
		doorbell = mana_ucontext->doorbell;
	} else {
		if (attr->cqe > U32_MAX / COMP_ENTRY_SIZE / 2 + 1) {
			ibdev_dbg(ibdev, "CQE %d exceeding limit\n", attr->cqe);
			return -EINVAL;
		}
		buf_size = MANA_PAGE_ALIGN(roundup_pow_of_two(attr->cqe * COMP_ENTRY_SIZE));
		cq->cqe = buf_size / COMP_ENTRY_SIZE;
		err = mana_ib_create_kernel_queue(mdev, buf_size, GDMA_CQ, &cq->queue);
		if (err) {
			ibdev_dbg(ibdev, "Failed to create kernel queue for create cq, %d\n", err);
			return err;
		}
		doorbell = mdev->gdma_dev->doorbell;
	}

	if (is_rnic_cq) {
		err = mana_ib_gd_create_cq(mdev, cq, doorbell);
		if (err) {
			ibdev_dbg(ibdev, "Failed to create RNIC cq, %d\n", err);
			goto err_destroy_queue;
		}

		err = mana_ib_install_cq_cb(mdev, cq);
		if (err) {
			ibdev_dbg(ibdev, "Failed to install cq callback, %d\n", err);
			goto err_destroy_rnic_cq;
		}
	}

	if (udata) {
		resp.cqid = cq->queue.id;
		err = ib_respond_udata(udata, resp);
		if (err)
			goto err_remove_cq_cb;
	}

	spin_lock_init(&cq->cq_lock);
	INIT_LIST_HEAD(&cq->list_send_qp);
	INIT_LIST_HEAD(&cq->list_recv_qp);

	return 0;

err_remove_cq_cb:
	mana_ib_remove_cq_cb(mdev, cq);
err_destroy_rnic_cq:
	mana_ib_gd_destroy_cq(mdev, cq);
err_destroy_queue:
	mana_ib_destroy_queue(mdev, &cq->queue);

	return err;
}

int mana_ib_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
{
	struct mana_ib_cq *cq = container_of(ibcq, struct mana_ib_cq, ibcq);
	struct ib_device *ibdev = ibcq->device;
	struct mana_ib_dev *mdev;

	mdev = container_of(ibdev, struct mana_ib_dev, ib_dev);

	mana_ib_remove_cq_cb(mdev, cq);

	/* Ignore return code as there is not much we can do about it.
	 * The error message is printed inside.
	 */
	mana_ib_gd_destroy_cq(mdev, cq);

	mana_ib_destroy_queue(mdev, &cq->queue);

	return 0;
}

static void mana_ib_cq_handler(void *ctx, struct gdma_queue *gdma_cq)
{
	struct mana_ib_cq *cq = ctx;

	if (cq->ibcq.comp_handler)
		cq->ibcq.comp_handler(&cq->ibcq, cq->ibcq.cq_context);
}

int mana_ib_install_cq_cb(struct mana_ib_dev *mdev, struct mana_ib_cq *cq)
{

Annotation

Implementation Notes