IBV_DEVICE_SYS_IMAGE_GUID = 1 << 11,
IBV_DEVICE_RC_RNR_NAK_GEN = 1 << 12,
IBV_DEVICE_SRQ_RESIZE = 1 << 13,
- IBV_DEVICE_N_NOTIFY_CQ = 1 << 14
+ IBV_DEVICE_N_NOTIFY_CQ = 1 << 14,
+ IBV_DEVICE_XRC = 1 << 20
};
enum ibv_atomic_cap {
enum ibv_qp_type {
IBV_QPT_RC = 2,
IBV_QPT_UC,
- IBV_QPT_UD
+ IBV_QPT_UD,
+ IBV_QPT_XRC_SEND = 9,
+ IBV_QPT_XRC_RECV
};
struct ibv_qp_cap {
int sq_sig_all;
};
+enum ibv_qp_init_attr_mask {
+ IBV_QP_INIT_ATTR_PD = 1 << 0,
+ IBV_QP_INIT_ATTR_XRCD = 1 << 1,
+ IBV_QP_INIT_ATTR_RESERVED = 1 << 2
+};
+
+struct ibv_qp_init_attr_ex {
+ void *qp_context;
+ struct ibv_cq *send_cq;
+ struct ibv_cq *recv_cq;
+ struct ibv_srq *srq;
+ struct ibv_qp_cap cap;
+ enum ibv_qp_type qp_type;
+ int sq_sig_all;
+
+ uint64_t comp_mask;
+ struct ibv_pd *pd;
+ struct ibv_xrcd *xrcd;
+};
+
enum ibv_qp_attr_mask {
IBV_QP_STATE = 1 << 0,
IBV_QP_CUR_STATE = 1 << 1,
uint32_t remote_qpn;
uint32_t remote_qkey;
} ud;
+ struct {
+ uint64_t reserved[3];
+ uint32_t reserved2;
+ uint32_t remote_srqn;
+ } xrc;
} wr;
};
int (*drv_new_func1) (); new corresponding provider call of func1
int (*lib_new_func1) (); New library call func1
*/
+ struct ibv_qp * (*create_qp_ex)(struct ibv_context *context,
+ struct ibv_qp_init_attr_ex *qp_init_attr_ex);
uint32_t (*get_srq_num)(struct ibv_srq *srq);
struct ibv_srq * (*create_srq_ex)(struct ibv_pd *pd,
struct ibv_srq_init_attr_ex *srq_init_attr_ex);
struct ibv_qp *ibv_create_qp(struct ibv_pd *pd,
struct ibv_qp_init_attr *qp_init_attr);
+static inline struct ibv_qp *
+ibv_create_qp_ex(struct ibv_context *context, struct ibv_qp_init_attr_ex *qp_init_attr_ex)
+{
+ struct verbs_context *vctx = verbs_get_ctx_op(context, create_qp_ex);
+ if (!vctx) {
+ errno = ENOSYS;
+ return NULL;
+ }
+ return vctx->create_qp_ex(context, qp_init_attr_ex);
+}
+
/**
* ibv_modify_qp - Modify a queue pair.
*/
return 0;
}
+int ibv_cmd_create_qp_ex(struct ibv_context *context,
+ struct verbs_qp *qp, struct ibv_qp_init_attr_ex *attr_ex,
+ struct ibv_create_qp *cmd, size_t cmd_size,
+ struct ibv_create_qp_resp *resp, size_t resp_size)
+{
+ struct ibv_context *context;
+ struct verbs_xrcd *vxrcd = NULL;
+
+ IBV_INIT_CMD_RESP(cmd, cmd_size, CREATE_QP, resp, resp_size);
+
+ cmd->user_handle = (uintptr_t) qp;
+
+ if (attr_ex->comp_mask & IBV_QP_INIT_ATTR_XRCD) {
+ vxrcd = container_of(attr_ex->xrcd, struct verbs_xrcd, xrcd);
+ context = vxrcd->xrcd.context;
+ cmd->pd_handle = vxrcd->handle;
+ } else {
+ context = pd->context;
+ cmd->pd_handle = pd->handle;
+ cmd->send_cq_handle = attr_ex->send_cq->handle;
+
+ if (attr_ex->qp_type != IBV_QPT_XRC_SEND) {
+ cmd->recv_cq_handle = attr_ex->recv_cq->handle;
+ cmd->srq_handle = attr_ex->srq ? attr_ex->srq->handle : 0;
+ }
+ }
+
+ cmd->max_send_wr = attr_ex->cap.max_send_wr;
+ cmd->max_recv_wr = attr_ex->cap.max_recv_wr;
+ cmd->max_send_sge = attr_ex->cap.max_send_sge;
+ cmd->max_recv_sge = attr_ex->cap.max_recv_sge;
+ cmd->max_inline_data = attr_ex->cap.max_inline_data;
+ cmd->sq_sig_all = attr_ex->sq_sig_all;
+ cmd->qp_type = attr_ex->qp_type;
+ cmd->is_srq = !!attr_ex->srq;
+ cmd->reserved = 0;
+
+ if (write(context->cmd_fd, cmd, cmd_size) != cmd_size)
+ return errno;
+
+ (void) VALGRIND_MAKE_MEM_DEFINED(resp, resp_size);
+
+ if (abi_ver > 3) {
+ attr_ex->cap.max_recv_sge = resp->max_recv_sge;
+ attr_ex->cap.max_send_sge = resp->max_send_sge;
+ attr_ex->cap.max_recv_wr = resp->max_recv_wr;
+ attr_ex->cap.max_send_wr = resp->max_send_wr;
+ attr_ex->cap.max_inline_data = resp->max_inline_data;
+ }
+
+ if (abi_ver == 4) {
+ struct ibv_create_qp_resp_v4 *resp_v4 =
+ (struct ibv_create_qp_resp_v4 *) resp;
+
+ memmove((void *) resp + sizeof *resp,
+ (void *) resp_v4 + sizeof *resp_v4,
+ resp_size - sizeof *resp);
+ } else if (abi_ver <= 3) {
+ struct ibv_create_qp_resp_v3 *resp_v3 =
+ (struct ibv_create_qp_resp_v3 *) resp;
+
+ memmove((void *) resp + sizeof *resp,
+ (void *) resp_v3 + sizeof *resp_v3,
+ resp_size - sizeof *resp);
+ }
+
+ qp->qp.handle = resp->qp_handle;
+ qp->qp.qp_num = resp->qpn;
+ qp->qp.context = context;
+ qp->qp.qp_context = qp_init_attr_ex->qp_context;
+ qp->qp.pd = pd;
+ qp->qp.send_cq = qp_init_attr_ex->send_cq;
+ qp->qp.recv_cq = qp_init_attr_ex->recv_cq;
+ qp->qp.srq = qp_init_attr_ex->srq;
+ qp->qp.qp_type = qp_init_attr_ex->qp_type;
+ qp->qp.state = IBV_QPS_RESET;
+ qp->qp.events_completed = 0;
+ pthread_mutex_init(&qp->qp.mutex, NULL);
+ pthread_cond_init(&qp->qp.cond, NULL);
+
+ qp->comp_mask = 0;
+ if (attr_ex->comp_mask & IBV_QP_INIT_ATTR_XRCD) {
+ qp->comp_mask |= VERBS_QP_XRCD;
+ qp->xrcd = vxrcd;
+ }
+
+ return 0;
+}
+
int ibv_cmd_create_qp(struct ibv_pd *pd,
struct ibv_qp *qp, struct ibv_qp_init_attr *attr,
struct ibv_create_qp *cmd, size_t cmd_size,
struct ibv_create_qp_resp *resp, size_t resp_size)
{
+ int ret;
+
IBV_INIT_CMD_RESP(cmd, cmd_size, CREATE_QP, resp, resp_size);
cmd->user_handle = (uintptr_t) qp;
- cmd->pd_handle = pd->handle;
+
+ context = pd->context;
+ cmd->pd_handle = pd->handle;
cmd->send_cq_handle = attr->send_cq->handle;
- cmd->recv_cq_handle = attr->recv_cq->handle;
- cmd->srq_handle = attr->srq ? attr->srq->handle : 0;
cmd->max_send_wr = attr->cap.max_send_wr;
cmd->max_recv_wr = attr->cap.max_recv_wr;
cmd->max_send_sge = attr->cap.max_send_sge;
cmd->is_srq = !!attr->srq;
cmd->reserved = 0;
- if (write(pd->context->cmd_fd, cmd, cmd_size) != cmd_size)
+ if (write(context->cmd_fd, cmd, cmd_size) != cmd_size)
return errno;
(void) VALGRIND_MAKE_MEM_DEFINED(resp, resp_size);
qp->handle = resp->qp_handle;
qp->qp_num = resp->qpn;
- qp->context = pd->context;
+ qp->context = context;
if (abi_ver > 3) {
- attr->cap.max_recv_sge = resp->max_recv_sge;
- attr->cap.max_send_sge = resp->max_send_sge;
- attr->cap.max_recv_wr = resp->max_recv_wr;
- attr->cap.max_send_wr = resp->max_send_wr;
- attr->cap.max_inline_data = resp->max_inline_data;
+ attr_ex->cap.max_recv_sge = resp->max_recv_sge;
+ attr_ex->cap.max_send_sge = resp->max_send_sge;
+ attr_ex->cap.max_recv_wr = resp->max_recv_wr;
+ attr_ex->cap.max_send_wr = resp->max_send_wr;
+ attr_ex->cap.max_inline_data = resp->max_inline_data;
}
if (abi_ver == 4) {
resp_size - sizeof *resp);
}
- return 0;
+ return ret;
}
int ibv_cmd_query_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,