Skip to content

Commit

Permalink
mlx5: Introduce devx APIs to create and destroy EQs
Browse files Browse the repository at this point in the history
Introduce mlx5dv_devx_create_eq() and mlx5dv_devx_destroy_eq() to create
and destroy EQ objects, respectively.

Signed-off-by: Mark Zhang <markzhang@nvidia.com>
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
  • Loading branch information
MarkZhang81 authored and Yishai Hadas committed Mar 10, 2022
1 parent 1383a56 commit cfdc3f2
Show file tree
Hide file tree
Showing 8 changed files with 248 additions and 0 deletions.
2 changes: 2 additions & 0 deletions debian/ibverbs-providers.symbols
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ libmlx5.so.1 ibverbs-providers #MINVER#
mlx5dv_dr_aso_other_domain_link@MLX5_1.22 38
mlx5dv_dr_aso_other_domain_unlink@MLX5_1.22 38
mlx5dv_devx_alloc_msi_vector@MLX5_1.23 40
mlx5dv_devx_create_eq@MLX5_1.23 40
mlx5dv_devx_destroy_eq@MLX5_1.23 40
mlx5dv_devx_free_msi_vector@MLX5_1.23 40
libefa.so.1 ibverbs-providers #MINVER#
* Build-Depends-Package: libibverbs-dev
Expand Down
2 changes: 2 additions & 0 deletions providers/mlx5/libmlx5.map
Original file line number Diff line number Diff line change
Expand Up @@ -215,5 +215,7 @@ MLX5_1.22 {
MLX5_1.23 {
global:
mlx5dv_devx_alloc_msi_vector;
mlx5dv_devx_create_eq;
mlx5dv_devx_destroy_eq;
mlx5dv_devx_free_msi_vector;
} MLX5_1.22;
2 changes: 2 additions & 0 deletions providers/mlx5/man/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ rdma_man_pages(
mlx5dv_devx_alloc_msi_vector.3.md
mlx5dv_devx_alloc_uar.3.md
mlx5dv_devx_create_cmd_comp.3.md
mlx5dv_devx_create_eq.3.md
mlx5dv_devx_create_event_channel.3.md
mlx5dv_devx_get_event.3.md
mlx5dv_devx_obj_create.3.md
Expand Down Expand Up @@ -61,6 +62,7 @@ rdma_alias_man_pages(
mlx5dv_devx_alloc_msi_vector.3 mlx5dv_devx_free_msi_vector.3
mlx5dv_devx_alloc_uar.3 mlx5dv_devx_free_uar.3
mlx5dv_devx_create_cmd_comp.3 mlx5dv_devx_destroy_cmd_comp.3
mlx5dv_devx_create_eq.3 mlx5dv_devx_destroy_eq.3
mlx5dv_devx_create_event_channel.3 mlx5dv_devx_destroy_event_channel.3
mlx5dv_devx_create_cmd_comp.3 mlx5dv_devx_get_async_cmd_comp.3
mlx5dv_devx_obj_create.3 mlx5dv_devx_general_cmd.3
Expand Down
83 changes: 83 additions & 0 deletions providers/mlx5/man/mlx5dv_devx_create_eq.3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
date: 2022-01-12
footer: mlx5
header: "mlx5 Programmer's Manual"
tagline: Verbs
layout: page
license: 'Licensed under the OpenIB.org BSD license (FreeBSD Variant) - See COPYING.md'
section: 3
title: mlx5dv_devx_create_eq
---

# NAME

mlx5dv_devx_create_eq - Create an EQ object

mlx5dv_devx_destroy_eq - Destroy an EQ object

# SYNOPSIS

```c
#include <infiniband/mlx5dv.h>

struct mlx5dv_devx_eq *
mlx5dv_devx_create_eq(struct ibv_context *ibctx, const void *in, size_t inlen,
void *out, size_t outlen);

int mlx5dv_devx_destroy_eq(struct mlx5dv_devx_eq *eq);

```
# DESCRIPTION
Create / Destroy an EQ object. Upon creation, the caller prepares the in/out mail boxes based on the device
specification format; For the input mailbox, caller needs to prepare all fields except "eqc.log_page_size"
and the pas list, which will be set by the driver. The "eqc.intr" field should be used from the output of
mlx5dv_devx_alloc_msi_vector().
# ARGUMENTS
*ibctx*
: RDMA device context to create the action on.
*in*
: A buffer which contains the command's input data provided in a device specification format.
*inlen*
: The size of *in* buffer in bytes.
*out*
: A buffer which contains the command's output data according to the device specification format.
*outlen*
: The size of *out* buffer in bytes.
*eq*
: The EQ object to work on.
```c
struct mlx5dv_devx_eq {
void *vaddr;
};
```

*vaddr*
: EQ VA that was allocated in the driver for.

# NOTES

mlx5dv_devx_query_eqn() will not support vectors which are used by mlx5dv_devx_create_eq().

# RETURN VALUE

Upon success *mlx5dv_devx_create_eq* will return a new *struct mlx5dv_devx_eq*;
On error NULL will be returned and errno will be set.

Upon success *mlx5dv_devx_destroy_eq* will return 0, on error errno will be returned.

# SEE ALSO

*mlx5dv_devx_alloc_msi_vector(3)*, *mlx5dv_devx_query_eqn(3)*

# AUTHOR

Mark Zhang <markzhang@nvidia.com>
12 changes: 12 additions & 0 deletions providers/mlx5/mlx5.h
Original file line number Diff line number Diff line change
Expand Up @@ -918,6 +918,14 @@ struct mlx5_devx_msi_vector {
struct ibv_context *ibctx;
};

struct mlx5_devx_eq {
struct mlx5dv_devx_eq dv_eq;
struct ibv_context *ibctx;
uint64_t iova;
size_t size;
int eqn;
};

struct ibv_flow *
_mlx5dv_create_flow(struct mlx5dv_flow_matcher *flow_matcher,
struct mlx5dv_flow_match_parameters *match_value,
Expand Down Expand Up @@ -1568,6 +1576,10 @@ struct mlx5_dv_context_ops {
int (*map_ah_to_qp)(struct ibv_ah *ah, uint32_t qp_num);
struct mlx5dv_devx_msi_vector *(*devx_alloc_msi_vector)(struct ibv_context *ibctx);
int (*devx_free_msi_vector)(struct mlx5dv_devx_msi_vector *msi);
struct mlx5dv_devx_eq *(*devx_create_eq)(struct ibv_context *ibctx,
const void *in, size_t inlen,
void *out, size_t outlen);
int (*devx_destroy_eq)(struct mlx5dv_devx_eq *eq);
};

struct mlx5_dv_context_ops *mlx5_get_dv_ops(struct ibv_context *context);
Expand Down
112 changes: 112 additions & 0 deletions providers/mlx5/mlx5_vfio.c
Original file line number Diff line number Diff line change
Expand Up @@ -3185,6 +3185,116 @@ static int vfio_devx_free_msi_vector(struct mlx5dv_devx_msi_vector *msi)
return ret;
}

static struct mlx5dv_devx_eq *
vfio_devx_create_eq(struct ibv_context *ibctx, const void *in, size_t inlen,
void *out, size_t outlen)
{
struct mlx5_vfio_context *ctx = to_mvfio_ctx(ibctx);
struct mlx5_devx_eq *eq;
void *eqc, *in_pas;
size_t inlen_pas;
uint64_t size;
__be64 *pas;
int err;

eqc = DEVX_ADDR_OF(create_eq_in, in, eq_context_entry);
if ((inlen < DEVX_ST_SZ_BYTES(create_eq_in)) ||
(DEVX_GET(create_eq_in, in, opcode) != MLX5_CMD_OP_CREATE_EQ) ||
(DEVX_GET(eqc, eqc, intr) == MLX5_VFIO_CMD_VEC_IDX)) {
errno = EINVAL;
return NULL;
}

size = max(roundup_pow_of_two(
(1ULL << DEVX_GET(eqc, eqc, log_eq_size)) * MLX5_EQE_SIZE),
ctx->iova_min_page_size);
if (size > SIZE_MAX) {
errno = ERANGE;
return NULL;
}

eq = calloc(1, sizeof(*eq));
if (!eq) {
errno = ENOMEM;
return NULL;
}

eq->size = size;
err = posix_memalign(&eq->dv_eq.vaddr,
MLX5_ADAPTER_PAGE_SIZE, eq->size);
if (err) {
errno = err;
goto err_va;
}

err = iset_alloc_range(ctx->iova_alloc, eq->size, &eq->iova);
if (err)
goto err_range;

err = mlx5_vfio_register_mem(ctx, eq->dv_eq.vaddr, eq->iova, eq->size);
if (err)
goto err_reg;

inlen_pas = inlen + DEVX_FLD_SZ_BYTES(create_eq_in, pas[0]) * 1;
in_pas = calloc(1, inlen_pas);
if (!in_pas) {
errno = ENOMEM;
goto err_inpas;
}

memcpy(in_pas, in, inlen);
eqc = DEVX_ADDR_OF(create_eq_in, in_pas, eq_context_entry);
DEVX_SET(eqc, eqc, log_page_size,
ilog32(eq->size - 1) - MLX5_ADAPTER_PAGE_SHIFT);

pas = (__be64 *)DEVX_ADDR_OF(create_eq_in, in_pas, pas);
pas[0] = htobe64(eq->iova);

err = mlx5_vfio_cmd_exec(ctx, in_pas, inlen_pas, out, outlen, 0);
if (err)
goto err_cmd;

free(in_pas);
eq->ibctx = ibctx;
eq->eqn = DEVX_GET(create_eq_out, out, eq_number);
return &eq->dv_eq;

err_cmd:
free(in_pas);
err_inpas:
mlx5_vfio_unregister_mem(ctx, eq->iova, eq->size);
err_reg:
iset_insert_range(ctx->iova_alloc, eq->iova, eq->size);
err_range:
free(eq->dv_eq.vaddr);
err_va:
free(eq);
return NULL;
}

static int vfio_devx_destroy_eq(struct mlx5dv_devx_eq *dveq)
{
struct mlx5_devx_eq *eq =
container_of(dveq, struct mlx5_devx_eq, dv_eq);
struct mlx5_vfio_context *ctx = to_mvfio_ctx(eq->ibctx);
uint32_t out[DEVX_ST_SZ_DW(destroy_eq_out)] = {};
uint32_t in[DEVX_ST_SZ_DW(destroy_eq_in)] = {};
int err;

DEVX_SET(destroy_eq_in, in, opcode, MLX5_CMD_OP_DESTROY_EQ);
DEVX_SET(destroy_eq_in, in, eq_number, eq->eqn);

err = mlx5_vfio_cmd_exec(ctx, in, sizeof(in), out, sizeof(out), 0);
if (err)
return err;

mlx5_vfio_unregister_mem(ctx, eq->iova, eq->size);
iset_insert_range(ctx->iova_alloc, eq->iova, eq->size);
free(eq);

return 0;
}

static struct mlx5_dv_context_ops mlx5_vfio_dv_ctx_ops = {
.devx_general_cmd = vfio_devx_general_cmd,
.devx_obj_create = vfio_devx_obj_create,
Expand All @@ -3200,6 +3310,8 @@ static struct mlx5_dv_context_ops mlx5_vfio_dv_ctx_ops = {
.init_obj = vfio_init_obj,
.devx_alloc_msi_vector = vfio_devx_alloc_msi_vector,
.devx_free_msi_vector = vfio_devx_free_msi_vector,
.devx_create_eq = vfio_devx_create_eq,
.devx_destroy_eq = vfio_devx_destroy_eq,
};

static void mlx5_vfio_uninit_context(struct mlx5_vfio_context *ctx)
Expand Down
9 changes: 9 additions & 0 deletions providers/mlx5/mlx5dv.h
Original file line number Diff line number Diff line change
Expand Up @@ -2145,6 +2145,15 @@ mlx5dv_devx_alloc_msi_vector(struct ibv_context *ibctx);

int mlx5dv_devx_free_msi_vector(struct mlx5dv_devx_msi_vector *msi);

struct mlx5dv_devx_eq {
void *vaddr;
};

struct mlx5dv_devx_eq *
mlx5dv_devx_create_eq(struct ibv_context *ibctx, const void *in, size_t inlen,
void *out, size_t outlen);

int mlx5dv_devx_destroy_eq(struct mlx5dv_devx_eq *eq);

#ifdef __cplusplus
}
Expand Down
26 changes: 26 additions & 0 deletions providers/mlx5/verbs.c
Original file line number Diff line number Diff line change
Expand Up @@ -7360,6 +7360,32 @@ int mlx5dv_devx_free_msi_vector(struct mlx5dv_devx_msi_vector *dvmsi)
return dvops->devx_free_msi_vector(dvmsi);
}

struct mlx5dv_devx_eq *
mlx5dv_devx_create_eq(struct ibv_context *ibctx, const void *in, size_t inlen,
void *out, size_t outlen)
{
struct mlx5_dv_context_ops *dvops = mlx5_get_dv_ops(ibctx);

if (!dvops || !dvops->devx_create_eq) {
errno = EOPNOTSUPP;
return NULL;
}

return dvops->devx_create_eq(ibctx, in, inlen, out, outlen);
}

int mlx5dv_devx_destroy_eq(struct mlx5dv_devx_eq *dveq)
{
struct mlx5_devx_eq *eq =
container_of(dveq, struct mlx5_devx_eq, dv_eq);
struct mlx5_dv_context_ops *dvops = mlx5_get_dv_ops(eq->ibctx);

if (!dvops || !dvops->devx_destroy_eq)
return EOPNOTSUPP;

return dvops->devx_destroy_eq(dveq);
}

void mlx5_set_dv_ctx_ops(struct mlx5_dv_context_ops *ops)
{
ops->devx_general_cmd = _mlx5dv_devx_general_cmd;
Expand Down

0 comments on commit cfdc3f2

Please sign in to comment.