Message ID | 1445964755-13371-3-git-send-email-matanb@mellanox.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
On Tue, Oct 27, 2015 at 6:52 PM, Matan Barak <matanb@mellanox.com> wrote: > Add an extension verb mlx4_create_cq_ex that follows the > standard extension verb mechanism. > This function is similar to mlx4_create_cq but supports the > extension verbs functions and stores the creation flags > for later use (for example, timestamp flag is used in poll_cq). > The function fails if the user passes unsupported WC attributes. > > Signed-off-by: Matan Barak <matanb@mellanox.com> > --- > src/mlx4-abi.h | 12 ++++++ > src/mlx4.c | 1 + > src/mlx4.h | 3 ++ > src/verbs.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++-------- > 4 files changed, 117 insertions(+), 16 deletions(-) > > diff --git a/src/mlx4-abi.h b/src/mlx4-abi.h > index b348ce3..9b765e4 100644 > --- a/src/mlx4-abi.h > +++ b/src/mlx4-abi.h > @@ -72,12 +72,24 @@ struct mlx4_create_cq { > __u64 db_addr; > }; > > +struct mlx4_create_cq_ex { > + struct ibv_create_cq_ex ibv_cmd; > + __u64 buf_addr; > + __u64 db_addr; > +}; > + > struct mlx4_create_cq_resp { > struct ibv_create_cq_resp ibv_resp; > __u32 cqn; > __u32 reserved; > }; > > +struct mlx4_create_cq_resp_ex { > + struct ibv_create_cq_resp_ex ibv_resp; > + __u32 cqn; > + __u32 reserved; > +}; > + > struct mlx4_resize_cq { > struct ibv_resize_cq ibv_cmd; > __u64 buf_addr; > diff --git a/src/mlx4.c b/src/mlx4.c > index d41dff0..9cfd013 100644 > --- a/src/mlx4.c > +++ b/src/mlx4.c > @@ -208,6 +208,7 @@ static int mlx4_init_context(struct verbs_device *v_device, > verbs_set_ctx_op(verbs_ctx, ibv_create_flow, ibv_cmd_create_flow); > verbs_set_ctx_op(verbs_ctx, ibv_destroy_flow, ibv_cmd_destroy_flow); > verbs_set_ctx_op(verbs_ctx, query_device_ex, mlx4_query_device_ex); > + verbs_set_ctx_op(verbs_ctx, create_cq_ex, mlx4_create_cq_ex); > > return 0; > > diff --git a/src/mlx4.h b/src/mlx4.h > index 0f643bc..91eb79c 100644 > --- a/src/mlx4.h > +++ b/src/mlx4.h > @@ -222,6 +222,7 @@ struct mlx4_cq { > uint32_t *arm_db; > int arm_sn; > int cqe_size; > + int creation_flags; > }; > > struct mlx4_srq { > @@ -402,6 +403,8 @@ int mlx4_dereg_mr(struct ibv_mr *mr); > struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe, > struct ibv_comp_channel *channel, > int comp_vector); > +struct ibv_cq *mlx4_create_cq_ex(struct ibv_context *context, > + struct ibv_create_cq_attr_ex *cq_attr); > int mlx4_alloc_cq_buf(struct mlx4_device *dev, struct mlx4_buf *buf, int nent, > int entry_size); > int mlx4_resize_cq(struct ibv_cq *cq, int cqe); > diff --git a/src/verbs.c b/src/verbs.c > index e93114b..3290b86 100644 > --- a/src/verbs.c > +++ b/src/verbs.c > @@ -272,19 +272,69 @@ int align_queue_size(int req) > return nent; > } > > -struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe, > - struct ibv_comp_channel *channel, > - int comp_vector) > +enum cmd_type { > + MLX4_CMD_TYPE_BASIC, > + MLX4_CMD_TYPE_EXTENDED > +}; > + > +enum { > + CREATE_CQ_SUPPORTED_COMP_MASK = IBV_CREATE_CQ_ATTR_FLAGS > +}; > + > +enum { > + CREATE_CQ_SUPPORTED_FLAGS = IBV_CREATE_CQ_ATTR_COMPLETION_TIMESTAMP > +}; > + > +enum { > + CREATE_CQ_SUPPORTED_WC_FLAGS = IBV_WC_STANDARD_FLAGS > +}; > + > +static struct ibv_cq *create_cq(struct ibv_context *context, > + struct ibv_create_cq_attr_ex *cq_attr, > + enum cmd_type cmd_type) > { > - struct mlx4_create_cq cmd; > - struct mlx4_create_cq_resp resp; > - struct mlx4_cq *cq; > - int ret; > - struct mlx4_context *mctx = to_mctx(context); > + struct mlx4_create_cq cmd; > + struct mlx4_create_cq_ex cmd_e; > + struct mlx4_create_cq_resp resp; > + struct mlx4_create_cq_resp_ex resp_e; > + struct mlx4_cq *cq; > + int ret; > + struct mlx4_context *mctx = to_mctx(context); > + struct ibv_create_cq_attr_ex cq_attr_e; > + int cqe; > > /* Sanity check CQ size before proceeding */ > - if (cqe > 0x3fffff) > + if (cq_attr->cqe > 0x3fffff) > + return NULL; > + > + if (cq_attr->comp_mask & ~CREATE_CQ_SUPPORTED_COMP_MASK) { > + errno = EINVAL; > return NULL; > + } > + > + if (cq_attr->comp_mask & IBV_CREATE_CQ_ATTR_FLAGS && > + cq_attr->flags & ~CREATE_CQ_SUPPORTED_FLAGS) { > + errno = EINVAL; > + return NULL; > + } > + > + if (cq_attr->wc_flags & ~CREATE_CQ_SUPPORTED_WC_FLAGS) { > + errno = ENOTSUP; > + return NULL; > + } > + > + if (!(cq_attr->wc_flags & IBV_WC_EX_WITH_COMPLETION_TIMESTAMP) != > + !(cq_attr->comp_mask & IBV_CREATE_CQ_ATTR_FLAGS && > + cq_attr->flags & IBV_CREATE_CQ_ATTR_COMPLETION_TIMESTAMP)) { > + errno = EINVAL; > + return NULL; > + } > + > + if (cq_attr->wc_flags & IBV_WC_EX_WITH_COMPLETION_TIMESTAMP && > + cq_attr->wc_flags & (IBV_WC_EX_WITH_SL | IBV_WC_EX_WITH_SLID)) { > + errno = EOPNOTSUPP; > + return NULL; > + } > > cq = malloc(sizeof *cq); > if (!cq) > @@ -295,9 +345,11 @@ struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe, > if (pthread_spin_init(&cq->lock, PTHREAD_PROCESS_PRIVATE)) > goto err; > > - cqe = align_queue_size(cqe + 1); > + cq_attr_e = *cq_attr; > + cqe = align_queue_size(cq_attr->cqe + 1); > > - if (mlx4_alloc_cq_buf(to_mdev(context->device), &cq->buf, cqe, mctx->cqe_size)) > + if (mlx4_alloc_cq_buf(to_mdev(context->device), &cq->buf, cqe, > + mctx->cqe_size)) > goto err; > > cq->cqe_size = mctx->cqe_size; > @@ -310,15 +362,31 @@ struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe, > cq->arm_sn = 1; > *cq->set_ci_db = 0; > > - cmd.buf_addr = (uintptr_t) cq->buf.buf; > - cmd.db_addr = (uintptr_t) cq->set_ci_db; > + if (cmd_type == MLX4_CMD_TYPE_BASIC) { > + cmd.buf_addr = (uintptr_t)cq->buf.buf; > + cmd.db_addr = (uintptr_t)cq->set_ci_db; > + > + ret = ibv_cmd_create_cq(context, cqe - 1, > + cq_attr_e.channel, cq_attr_e.comp_vector, > + &cq->ibv_cq, &cmd.ibv_cmd, sizeof(cmd), > + &resp.ibv_resp, sizeof(resp)); > + } else { > + cmd_e.buf_addr = (uintptr_t)cq->buf.buf; > + cmd_e.db_addr = (uintptr_t)cq->set_ci_db; > + > + cq_attr_e.cqe = cqe - 1; > + ret = ibv_cmd_create_cq_ex(context, &cq_attr_e, &cq->ibv_cq, > + &cmd_e.ibv_cmd, > + sizeof(cmd_e.ibv_cmd), sizeof(cmd_e), > + &resp_e.ibv_resp, > + sizeof(resp_e.ibv_resp), > + sizeof(resp_e)); > + } > > - ret = ibv_cmd_create_cq(context, cqe - 1, channel, comp_vector, > - &cq->ibv_cq, &cmd.ibv_cmd, sizeof cmd, > - &resp.ibv_resp, sizeof resp); > if (ret) > goto err_db; > > + cq->creation_flags = cmd_e.ibv_cmd.flags; > cq->cqn = resp.cqn; > > return &cq->ibv_cq; > @@ -335,6 +403,23 @@ err: > return NULL; > } > > +struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe, > + struct ibv_comp_channel *channel, > + int comp_vector) > +{ > + struct ibv_create_cq_attr_ex attr = {.cqe = cqe, .channel = channel, > + .comp_vector = comp_vector, > + .wc_flags = IBV_WC_STANDARD_FLAGS}; > + > + return create_cq(context, &attr, MLX4_CMD_TYPE_BASIC); > +} > + > +struct ibv_cq *mlx4_create_cq_ex(struct ibv_context *context, > + struct ibv_create_cq_attr_ex *cq_attr) > +{ > + return create_cq(context, cq_attr, MLX4_CMD_TYPE_EXTENDED); > +} > + > int mlx4_resize_cq(struct ibv_cq *ibcq, int cqe) > { > struct mlx4_cq *cq = to_mcq(ibcq); > -- > 2.1.0 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-rdma" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html This should have libmlx4 prefix. -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/src/mlx4-abi.h b/src/mlx4-abi.h index b348ce3..9b765e4 100644 --- a/src/mlx4-abi.h +++ b/src/mlx4-abi.h @@ -72,12 +72,24 @@ struct mlx4_create_cq { __u64 db_addr; }; +struct mlx4_create_cq_ex { + struct ibv_create_cq_ex ibv_cmd; + __u64 buf_addr; + __u64 db_addr; +}; + struct mlx4_create_cq_resp { struct ibv_create_cq_resp ibv_resp; __u32 cqn; __u32 reserved; }; +struct mlx4_create_cq_resp_ex { + struct ibv_create_cq_resp_ex ibv_resp; + __u32 cqn; + __u32 reserved; +}; + struct mlx4_resize_cq { struct ibv_resize_cq ibv_cmd; __u64 buf_addr; diff --git a/src/mlx4.c b/src/mlx4.c index d41dff0..9cfd013 100644 --- a/src/mlx4.c +++ b/src/mlx4.c @@ -208,6 +208,7 @@ static int mlx4_init_context(struct verbs_device *v_device, verbs_set_ctx_op(verbs_ctx, ibv_create_flow, ibv_cmd_create_flow); verbs_set_ctx_op(verbs_ctx, ibv_destroy_flow, ibv_cmd_destroy_flow); verbs_set_ctx_op(verbs_ctx, query_device_ex, mlx4_query_device_ex); + verbs_set_ctx_op(verbs_ctx, create_cq_ex, mlx4_create_cq_ex); return 0; diff --git a/src/mlx4.h b/src/mlx4.h index 0f643bc..91eb79c 100644 --- a/src/mlx4.h +++ b/src/mlx4.h @@ -222,6 +222,7 @@ struct mlx4_cq { uint32_t *arm_db; int arm_sn; int cqe_size; + int creation_flags; }; struct mlx4_srq { @@ -402,6 +403,8 @@ int mlx4_dereg_mr(struct ibv_mr *mr); struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe, struct ibv_comp_channel *channel, int comp_vector); +struct ibv_cq *mlx4_create_cq_ex(struct ibv_context *context, + struct ibv_create_cq_attr_ex *cq_attr); int mlx4_alloc_cq_buf(struct mlx4_device *dev, struct mlx4_buf *buf, int nent, int entry_size); int mlx4_resize_cq(struct ibv_cq *cq, int cqe); diff --git a/src/verbs.c b/src/verbs.c index e93114b..3290b86 100644 --- a/src/verbs.c +++ b/src/verbs.c @@ -272,19 +272,69 @@ int align_queue_size(int req) return nent; } -struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe, - struct ibv_comp_channel *channel, - int comp_vector) +enum cmd_type { + MLX4_CMD_TYPE_BASIC, + MLX4_CMD_TYPE_EXTENDED +}; + +enum { + CREATE_CQ_SUPPORTED_COMP_MASK = IBV_CREATE_CQ_ATTR_FLAGS +}; + +enum { + CREATE_CQ_SUPPORTED_FLAGS = IBV_CREATE_CQ_ATTR_COMPLETION_TIMESTAMP +}; + +enum { + CREATE_CQ_SUPPORTED_WC_FLAGS = IBV_WC_STANDARD_FLAGS +}; + +static struct ibv_cq *create_cq(struct ibv_context *context, + struct ibv_create_cq_attr_ex *cq_attr, + enum cmd_type cmd_type) { - struct mlx4_create_cq cmd; - struct mlx4_create_cq_resp resp; - struct mlx4_cq *cq; - int ret; - struct mlx4_context *mctx = to_mctx(context); + struct mlx4_create_cq cmd; + struct mlx4_create_cq_ex cmd_e; + struct mlx4_create_cq_resp resp; + struct mlx4_create_cq_resp_ex resp_e; + struct mlx4_cq *cq; + int ret; + struct mlx4_context *mctx = to_mctx(context); + struct ibv_create_cq_attr_ex cq_attr_e; + int cqe; /* Sanity check CQ size before proceeding */ - if (cqe > 0x3fffff) + if (cq_attr->cqe > 0x3fffff) + return NULL; + + if (cq_attr->comp_mask & ~CREATE_CQ_SUPPORTED_COMP_MASK) { + errno = EINVAL; return NULL; + } + + if (cq_attr->comp_mask & IBV_CREATE_CQ_ATTR_FLAGS && + cq_attr->flags & ~CREATE_CQ_SUPPORTED_FLAGS) { + errno = EINVAL; + return NULL; + } + + if (cq_attr->wc_flags & ~CREATE_CQ_SUPPORTED_WC_FLAGS) { + errno = ENOTSUP; + return NULL; + } + + if (!(cq_attr->wc_flags & IBV_WC_EX_WITH_COMPLETION_TIMESTAMP) != + !(cq_attr->comp_mask & IBV_CREATE_CQ_ATTR_FLAGS && + cq_attr->flags & IBV_CREATE_CQ_ATTR_COMPLETION_TIMESTAMP)) { + errno = EINVAL; + return NULL; + } + + if (cq_attr->wc_flags & IBV_WC_EX_WITH_COMPLETION_TIMESTAMP && + cq_attr->wc_flags & (IBV_WC_EX_WITH_SL | IBV_WC_EX_WITH_SLID)) { + errno = EOPNOTSUPP; + return NULL; + } cq = malloc(sizeof *cq); if (!cq) @@ -295,9 +345,11 @@ struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe, if (pthread_spin_init(&cq->lock, PTHREAD_PROCESS_PRIVATE)) goto err; - cqe = align_queue_size(cqe + 1); + cq_attr_e = *cq_attr; + cqe = align_queue_size(cq_attr->cqe + 1); - if (mlx4_alloc_cq_buf(to_mdev(context->device), &cq->buf, cqe, mctx->cqe_size)) + if (mlx4_alloc_cq_buf(to_mdev(context->device), &cq->buf, cqe, + mctx->cqe_size)) goto err; cq->cqe_size = mctx->cqe_size; @@ -310,15 +362,31 @@ struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe, cq->arm_sn = 1; *cq->set_ci_db = 0; - cmd.buf_addr = (uintptr_t) cq->buf.buf; - cmd.db_addr = (uintptr_t) cq->set_ci_db; + if (cmd_type == MLX4_CMD_TYPE_BASIC) { + cmd.buf_addr = (uintptr_t)cq->buf.buf; + cmd.db_addr = (uintptr_t)cq->set_ci_db; + + ret = ibv_cmd_create_cq(context, cqe - 1, + cq_attr_e.channel, cq_attr_e.comp_vector, + &cq->ibv_cq, &cmd.ibv_cmd, sizeof(cmd), + &resp.ibv_resp, sizeof(resp)); + } else { + cmd_e.buf_addr = (uintptr_t)cq->buf.buf; + cmd_e.db_addr = (uintptr_t)cq->set_ci_db; + + cq_attr_e.cqe = cqe - 1; + ret = ibv_cmd_create_cq_ex(context, &cq_attr_e, &cq->ibv_cq, + &cmd_e.ibv_cmd, + sizeof(cmd_e.ibv_cmd), sizeof(cmd_e), + &resp_e.ibv_resp, + sizeof(resp_e.ibv_resp), + sizeof(resp_e)); + } - ret = ibv_cmd_create_cq(context, cqe - 1, channel, comp_vector, - &cq->ibv_cq, &cmd.ibv_cmd, sizeof cmd, - &resp.ibv_resp, sizeof resp); if (ret) goto err_db; + cq->creation_flags = cmd_e.ibv_cmd.flags; cq->cqn = resp.cqn; return &cq->ibv_cq; @@ -335,6 +403,23 @@ err: return NULL; } +struct ibv_cq *mlx4_create_cq(struct ibv_context *context, int cqe, + struct ibv_comp_channel *channel, + int comp_vector) +{ + struct ibv_create_cq_attr_ex attr = {.cqe = cqe, .channel = channel, + .comp_vector = comp_vector, + .wc_flags = IBV_WC_STANDARD_FLAGS}; + + return create_cq(context, &attr, MLX4_CMD_TYPE_BASIC); +} + +struct ibv_cq *mlx4_create_cq_ex(struct ibv_context *context, + struct ibv_create_cq_attr_ex *cq_attr) +{ + return create_cq(context, cq_attr, MLX4_CMD_TYPE_EXTENDED); +} + int mlx4_resize_cq(struct ibv_cq *ibcq, int cqe) { struct mlx4_cq *cq = to_mcq(ibcq);
Add an extension verb mlx4_create_cq_ex that follows the standard extension verb mechanism. This function is similar to mlx4_create_cq but supports the extension verbs functions and stores the creation flags for later use (for example, timestamp flag is used in poll_cq). The function fails if the user passes unsupported WC attributes. Signed-off-by: Matan Barak <matanb@mellanox.com> --- src/mlx4-abi.h | 12 ++++++ src/mlx4.c | 1 + src/mlx4.h | 3 ++ src/verbs.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 117 insertions(+), 16 deletions(-)