Skip to content

Commit

Permalink
mlx5: Implement set and query ECE verbs
Browse files Browse the repository at this point in the history
Provide an implementation of set and query ECE, both verbs
are expected to be called through RDMA-CM while doing ECE
handshake.

Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
  • Loading branch information
Leon Romanovsky committed Jun 15, 2020
1 parent cf053bc commit 6957c18
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 14 deletions.
2 changes: 1 addition & 1 deletion providers/mlx5/mlx5-abi.h
Expand Up @@ -90,7 +90,7 @@ struct mlx5_modify_qp {
struct ibv_modify_qp_ex ibv_cmd;
__u32 comp_mask;
struct mlx5_ib_burst_info burst_info;
__u32 reserved;
__u32 ece_options;
};

#endif /* MLX5_ABI_H */
9 changes: 5 additions & 4 deletions providers/mlx5/mlx5.c
Expand Up @@ -51,10 +51,6 @@

static void mlx5_free_context(struct ibv_context *ibctx);

#ifndef PCI_VENDOR_ID_MELLANOX
#define PCI_VENDOR_ID_MELLANOX 0x15b3
#endif

#ifndef CPU_OR
#define CPU_OR(x, y, z) do {} while (0)
#endif
Expand Down Expand Up @@ -155,11 +151,13 @@ static const struct verbs_context_ops mlx5_ctx_common_ops = {
.open_xrcd = mlx5_open_xrcd,
.post_srq_ops = mlx5_post_srq_ops,
.query_device_ex = mlx5_query_device_ex,
.query_ece = mlx5_query_ece,
.query_rt_values = mlx5_query_rt_values,
.read_counters = mlx5_read_counters,
.reg_dm_mr = mlx5_reg_dm_mr,
.alloc_null_mr = mlx5_alloc_null_mr,
.free_context = mlx5_free_context,
.set_ece = mlx5_set_ece,
};

static const struct verbs_context_ops mlx5_ctx_cqev1_ops = {
Expand Down Expand Up @@ -1406,6 +1404,9 @@ static struct verbs_context *mlx5_alloc_context(struct ibv_device *ibdev,
context->max_srq_recv_wr = resp.max_srq_recv_wr;
context->num_dyn_bfregs = resp.num_dyn_bfregs;

if (resp.comp_mask & MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_ECE)
context->flags |= MLX5_CTX_FLAGS_ECE_SUPPORTED;

if (resp.comp_mask & MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_DUMP_FILL_MKEY) {
context->dump_fill_mkey = resp.dump_fill_mkey;
/* Have the BE value ready to be used in data path */
Expand Down
21 changes: 21 additions & 0 deletions providers/mlx5/mlx5.h
Expand Up @@ -51,6 +51,10 @@

#define PFX "mlx5: "

#ifndef PCI_VENDOR_ID_MELLANOX
#define PCI_VENDOR_ID_MELLANOX 0x15b3
#endif

typedef _Atomic(uint32_t) atomic_uint32_t;

enum {
Expand Down Expand Up @@ -233,6 +237,7 @@ struct mlx5_uar_info {
enum mlx5_ctx_flags {
MLX5_CTX_FLAGS_FATAL_STATE = 1 << 0,
MLX5_CTX_FLAGS_NO_KERN_DYN_UAR = 1 << 1,
MLX5_CTX_FLAGS_ECE_SUPPORTED = 1 << 2,
};

struct mlx5_lag_caps {
Expand Down Expand Up @@ -598,6 +603,19 @@ struct mlx5_qp {
uint32_t rqn;
uint32_t sqn;
uint64_t tir_icm_addr;
/*
* ECE configuration is done in create/modify QP stages,
* so this value is cached version of the requested ECE prior
* to its execution. This field will be cleared after successful
* call to relevant "executor".
*/
uint32_t set_ece;
/*
* This field indicates returned ECE options from the device
* as were received from the HW in previous stage. Every
* write to the set_ece will clear this field.
*/
uint32_t get_ece;
};

struct mlx5_ah {
Expand Down Expand Up @@ -1030,6 +1048,9 @@ void clean_dyn_uars(struct ibv_context *context);
struct mlx5_bf *mlx5_attach_dedicated_uar(struct ibv_context *context,
uint32_t flags);

int mlx5_set_ece(struct ibv_qp *qp, struct ibv_ece *ece);
int mlx5_query_ece(struct ibv_qp *qp, struct ibv_ece *ece);

static inline void *mlx5_find_uidx(struct mlx5_context *ctx, uint32_t uidx)
{
int tind = uidx >> MLX5_UIDX_TABLE_SHIFT;
Expand Down
77 changes: 68 additions & 9 deletions providers/mlx5/verbs.c
Expand Up @@ -1842,6 +1842,42 @@ static void mlx5_free_qp_buf(struct mlx5_context *ctx, struct mlx5_qp *qp)
free(qp->sq.wr_data);
}

int mlx5_set_ece(struct ibv_qp *qp, struct ibv_ece *ece)
{
struct mlx5_context *context = to_mctx(qp->context);
struct mlx5_qp *mqp = to_mqp(qp);

if (ece->comp_mask) {
errno = EINVAL;
return errno;
}

if (ece->vendor_id != PCI_VENDOR_ID_MELLANOX) {
errno = EINVAL;
return errno;
}

if (!(context->flags & MLX5_CTX_FLAGS_ECE_SUPPORTED)) {
errno = EOPNOTSUPP;
return errno;
}

mqp->set_ece = ece->options;
/* Clean previously returned ECE options */
mqp->get_ece = 0;
return 0;
}

int mlx5_query_ece(struct ibv_qp *qp, struct ibv_ece *ece)
{
struct mlx5_qp *mqp = to_mqp(qp);

ece->vendor_id = PCI_VENDOR_ID_MELLANOX;
ece->options = mqp->get_ece;
ece->comp_mask = 0;
return 0;
}

static int mlx5_cmd_create_rss_qp(struct ibv_context *context,
struct ibv_qp_init_attr_ex *attr,
struct mlx5_qp *qp,
Expand Down Expand Up @@ -1988,6 +2024,9 @@ static int create_dct(struct ibv_context *context,
}
}
cmd.uidx = usr_idx;
if (ctx->flags & MLX5_CTX_FLAGS_ECE_SUPPORTED)
/* Create QP should start from ECE version 1 as a trigger */
cmd.ece_options = 0x10000000;

ret = ibv_cmd_create_qp_ex(context, &qp->verbs_qp,
attr, &cmd.ibv_cmd, sizeof(cmd),
Expand All @@ -1999,6 +2038,7 @@ static int create_dct(struct ibv_context *context,
return ret;
}

qp->get_ece = resp.ece_options;
qp->dc_type = MLX5DV_DCTYPE_DCT;
qp->rsc.type = MLX5_RSC_TYPE_QP;
if (ctx->cqe_version)
Expand Down Expand Up @@ -2286,6 +2326,10 @@ static struct ibv_qp *create_qp(struct ibv_context *context,
}
}

if (ctx->flags & MLX5_CTX_FLAGS_ECE_SUPPORTED)
/* Create QP should start from ECE version 1 as a trigger */
cmd.ece_options = 0x10000000;

if (attr->comp_mask & MLX5_CREATE_QP_EX2_COMP_MASK)
ret = mlx5_cmd_create_qp_ex(context, attr, &cmd, qp, &resp_ex);
else
Expand All @@ -2311,6 +2355,7 @@ static struct ibv_qp *create_qp(struct ibv_context *context,
pthread_mutex_unlock(&ctx->qp_table_mutex);
}

qp->get_ece = resp_drv->ece_options;
map_uuar(context, qp, resp_drv->bfreg_index, bf);

qp->rq.max_post = qp->rq.wqe_cnt;
Expand Down Expand Up @@ -2528,16 +2573,18 @@ enum {
static int modify_dct(struct ibv_qp *qp, struct ibv_qp_attr *attr,
int attr_mask)
{
struct ibv_modify_qp_ex cmd_ex = {};
struct mlx5_modify_qp cmd_ex = {};
struct mlx5_modify_qp_ex_resp resp = {};
struct mlx5_qp *mqp = to_mqp(qp);
struct mlx5_context *context = to_mctx(qp->context);
int min_resp_size;
bool dct_create;
int ret;

ret = ibv_cmd_modify_qp_ex(qp, attr, attr_mask, &cmd_ex, sizeof(cmd_ex),
&resp.ibv_resp, sizeof(resp));
cmd_ex.ece_options = mqp->set_ece;
ret = ibv_cmd_modify_qp_ex(qp, attr, attr_mask, &cmd_ex.ibv_cmd,
sizeof(cmd_ex), &resp.ibv_resp,
sizeof(resp));
if (ret)
return ret;

Expand All @@ -2563,6 +2610,10 @@ static int modify_dct(struct ibv_qp *qp, struct ibv_qp_attr *attr,
}

qp->qp_num = resp.dctn;
if (mqp->set_ece) {
mqp->set_ece = 0;
mqp->get_ece = resp.ece_options;
}

if (!context->cqe_version) {
pthread_mutex_lock(&context->qp_table_mutex);
Expand All @@ -2581,8 +2632,8 @@ int mlx5_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
int attr_mask)
{
struct ibv_modify_qp cmd = {};
struct ibv_modify_qp_ex cmd_ex = {};
struct ib_uverbs_ex_modify_qp_resp resp = {};
struct mlx5_modify_qp cmd_ex = {};
struct mlx5_modify_qp_ex_resp resp = {};
struct mlx5_qp *mqp = to_mqp(qp);
struct mlx5_context *context = to_mctx(qp->context);
int ret;
Expand Down Expand Up @@ -2627,12 +2678,20 @@ int mlx5_modify_qp(struct ibv_qp *qp, struct ibv_qp_attr *attr,
}
}

if (attr_mask & MLX5_MODIFY_QP_EX_ATTR_MASK)
ret = ibv_cmd_modify_qp_ex(qp, attr, attr_mask, &cmd_ex,
sizeof(cmd_ex), &resp, sizeof(resp));
else
if (attr_mask & MLX5_MODIFY_QP_EX_ATTR_MASK || mqp->set_ece) {
cmd_ex.ece_options = mqp->set_ece;
ret = ibv_cmd_modify_qp_ex(qp, attr, attr_mask, &cmd_ex.ibv_cmd,
sizeof(cmd_ex), &resp.ibv_resp,
sizeof(resp));
} else {
ret = ibv_cmd_modify_qp(qp, attr, attr_mask,
&cmd, sizeof(cmd));
}

if (!ret && mqp->set_ece) {
mqp->set_ece = 0;
mqp->get_ece = resp.ece_options;
}

if (!ret &&
(attr_mask & IBV_QP_STATE) &&
Expand Down

0 comments on commit 6957c18

Please sign in to comment.