drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c

Source file repositories/reference/linux-study-clean/drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c

File Facts

System
Linux kernel
Corpus path
drivers/infiniband/hw/vmw_pvrdma/pvrdma_srq.c
Extension
.c
Size
9042 bytes
Lines
304
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

#include <asm/page.h>
#include <linux/io.h>
#include <linux/wait.h>
#include <rdma/ib_addr.h>
#include <rdma/ib_smi.h>
#include <rdma/ib_user_verbs.h>
#include <rdma/uverbs_ioctl.h>

#include "pvrdma.h"

/**
 * pvrdma_query_srq - query shared receive queue
 * @ibsrq: the shared receive queue to query
 * @srq_attr: attributes to query and return to client
 *
 * @return: 0 for success, otherwise returns an errno.
 */
int pvrdma_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
{
	struct pvrdma_dev *dev = to_vdev(ibsrq->device);
	struct pvrdma_srq *srq = to_vsrq(ibsrq);
	union pvrdma_cmd_req req;
	union pvrdma_cmd_resp rsp;
	struct pvrdma_cmd_query_srq *cmd = &req.query_srq;
	struct pvrdma_cmd_query_srq_resp *resp = &rsp.query_srq_resp;
	int ret;

	memset(cmd, 0, sizeof(*cmd));
	cmd->hdr.cmd = PVRDMA_CMD_QUERY_SRQ;
	cmd->srq_handle = srq->srq_handle;

	ret = pvrdma_cmd_post(dev, &req, &rsp, PVRDMA_CMD_QUERY_SRQ_RESP);
	if (ret < 0) {
		dev_warn(&dev->pdev->dev,
			 "could not query shared receive queue, error: %d\n",
			 ret);
		return -EINVAL;
	}

	srq_attr->srq_limit = resp->attrs.srq_limit;
	srq_attr->max_wr = resp->attrs.max_wr;
	srq_attr->max_sge = resp->attrs.max_sge;

	return 0;
}

/**
 * pvrdma_create_srq - create shared receive queue
 * @ibsrq: the IB shared receive queue
 * @init_attr: shared receive queue attributes
 * @udata: user data
 *
 * @return: 0 on success, otherwise returns an errno.
 */
int pvrdma_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init_attr,
		      struct ib_udata *udata)
{
	struct pvrdma_srq *srq = to_vsrq(ibsrq);
	struct pvrdma_dev *dev = to_vdev(ibsrq->device);
	union pvrdma_cmd_req req;
	union pvrdma_cmd_resp rsp;
	struct pvrdma_cmd_create_srq *cmd = &req.create_srq;
	struct pvrdma_cmd_create_srq_resp *resp = &rsp.create_srq_resp;
	struct pvrdma_create_srq_resp srq_resp = {};
	struct pvrdma_create_srq ucmd;
	unsigned long flags;
	int ret;

	if (!udata) {
		/* No support for kernel clients. */
		dev_warn(&dev->pdev->dev,
			 "no shared receive queue support for kernel client\n");
		return -EOPNOTSUPP;
	}

	if (init_attr->srq_type != IB_SRQT_BASIC) {
		dev_warn(&dev->pdev->dev,
			 "shared receive queue type %d not supported\n",
			 init_attr->srq_type);
		return -EOPNOTSUPP;
	}

	if (init_attr->attr.max_wr  > dev->dsr->caps.max_srq_wr ||
	    init_attr->attr.max_sge > dev->dsr->caps.max_srq_sge) {
		dev_warn(&dev->pdev->dev,
			 "shared receive queue size invalid\n");
		return -EINVAL;
	}

	if (!atomic_add_unless(&dev->num_srqs, 1, dev->dsr->caps.max_srq))

Annotation

Implementation Notes