@@ -58,4 +58,6 @@ libmlx5.so.1 ibverbs-providers #MINVER#
mlx5dv_devx_destroy_cmd_comp@MLX5_1.9 23
mlx5dv_devx_get_async_cmd_comp@MLX5_1.9 23
mlx5dv_devx_obj_query_async@MLX5_1.9 23
+ mlx5dv_create_mkey@MLX5_1.10 24
+ mlx5dv_destroy_mkey@MLX5_1.10 24
mlx5dv_qp_ex_from_ibv_qp_ex@MLX5_1.10 24
@@ -83,5 +83,7 @@ MLX5_1.9 {
MLX5_1.10 {
global:
+ mlx5dv_create_mkey;
+ mlx5dv_destroy_mkey;
mlx5dv_qp_ex_from_ibv_qp_ex;
} MLX5_1.9;
@@ -4,6 +4,7 @@ rdma_man_pages(
mlx5dv_create_flow_action_modify_header.3.md
mlx5dv_create_flow_action_packet_reformat.3.md
mlx5dv_create_flow_matcher.3.md
+ mlx5dv_create_mkey.3.md
mlx5dv_create_qp.3.md
mlx5dv_devx_alloc_uar.3.md
mlx5dv_devx_create_cmd_comp.3.md
@@ -22,6 +23,7 @@ rdma_man_pages(
mlx5dv.7
)
rdma_alias_man_pages(
+ mlx5dv_create_mkey.3 mlx5dv_destroy_mkey.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_cmd_comp.3 mlx5dv_devx_get_async_cmd_comp.3
new file mode 100644
@@ -0,0 +1,75 @@
+---
+layout: page
+title: mlx5dv_create_mkey / mlx5dv_destroy_mkey
+section: 3
+tagline: Verbs
+---
+
+# NAME
+
+mlx5dv_create_mkey - Creates an indirect mkey
+
+mlx5dv_create_mkey - Destroys an indirect mkey
+
+# SYNOPSIS
+
+```c
+#include <infiniband/mlx5dv.h>
+
+struct mlx5dv_mkey_init_attr {
+ struct ibv_pd *pd;
+ uint32_t create_flags;
+ uint16_t max_entries;
+};
+
+struct mlx5dv_mkey {
+ uint32_t lkey;
+ uint32_t rkey;
+};
+
+struct mlx5dv_mkey *
+mlx5dv_create_mkey(struct mlx5dv_mkey_init_attr *mkey_init_attr);
+
+int mlx5dv_destroy_mkey(struct mlx5dv_mkey *mkey);
+
+```
+
+# DESCRIPTION
+
+Create / destroy an indirect mkey.
+
+Create an indirect mkey to enable application uses its specific device functionality.
+
+# ARGUMENTS
+
+##mkey_init_attr##
+
+*pd*
+: ibv protection domain.
+
+*create_flags*
+: MLX5DV_MKEY_INIT_ATTR_FLAGS_INDIRECT:
+ Indirect mkey is being created.
+
+*max_entries*
+: Requested max number of pointed entries by this indirect mkey.
+ The function will update the *mkey_init_attr->max_entries* with the actual mkey value that was created; it will be greater than or equal to the value requested.
+
+# RETURN VALUE
+
+Upon success *mlx5dv_create_mkey* will return a new *struct
+mlx5dv_mkey* on error NULL will be returned and errno will be set.
+
+Upon success destroy 0 is returned or the value of errno on a failure.
+
+# Notes
+
+To let this functionality works a DEVX context should be opened by using *mlx5dv_open_device*.
+
+# SEE ALSO
+
+**mlx5dv_open_device**
+
+#AUTHOR
+
+Yishai Hadas <yishaih@mellanox.com>
@@ -601,6 +601,12 @@ struct mlx5_devx_umem {
uint32_t handle;
};
+struct mlx5_mkey {
+ struct mlx5dv_mkey dv_mkey;
+ struct mlx5dv_devx_obj *devx_obj;
+ uint16_t num_desc;
+};
+
static inline int mlx5_ilog2(int n)
{
int t;
@@ -38,6 +38,7 @@ enum mlx5_cap_mode {
enum {
MLX5_CMD_OP_QUERY_HCA_CAP = 0x100,
+ MLX5_CMD_OP_CREATE_MKEY = 0x200,
};
struct mlx5_ifc_atomic_caps_bits {
@@ -98,3 +99,91 @@ struct mlx5_ifc_query_hca_cap_in_bits {
enum mlx5_cap_type {
MLX5_CAP_ATOMIC = 3,
};
+
+enum {
+ MLX5_MKC_ACCESS_MODE_KLMS = 0x2,
+};
+
+struct mlx5_ifc_mkc_bits {
+ u8 reserved_at_0[0x1];
+ u8 free[0x1];
+ u8 reserved_at_2[0x1];
+ u8 access_mode_4_2[0x3];
+ u8 reserved_at_6[0x7];
+ u8 relaxed_ordering_write[0x1];
+ u8 reserved_at_e[0x1];
+ u8 small_fence_on_rdma_read_response[0x1];
+ u8 umr_en[0x1];
+ u8 a[0x1];
+ u8 rw[0x1];
+ u8 rr[0x1];
+ u8 lw[0x1];
+ u8 lr[0x1];
+ u8 access_mode_1_0[0x2];
+ u8 reserved_at_18[0x8];
+
+ u8 qpn[0x18];
+ u8 mkey_7_0[0x8];
+
+ u8 reserved_at_40[0x20];
+
+ u8 length64[0x1];
+ u8 bsf_en[0x1];
+ u8 sync_umr[0x1];
+ u8 reserved_at_63[0x2];
+ u8 expected_sigerr_count[0x1];
+ u8 reserved_at_66[0x1];
+ u8 en_rinval[0x1];
+ u8 pd[0x18];
+
+ u8 start_addr[0x40];
+
+ u8 len[0x40];
+
+ u8 bsf_octword_size[0x20];
+
+ u8 reserved_at_120[0x80];
+
+ u8 translations_octword_size[0x20];
+
+ u8 reserved_at_1c0[0x1b];
+ u8 log_page_size[0x5];
+
+ u8 reserved_at_1e0[0x20];
+};
+
+struct mlx5_ifc_create_mkey_out_bits {
+ u8 status[0x8];
+ u8 reserved_at_8[0x18];
+
+ u8 syndrome[0x20];
+
+ u8 reserved_at_40[0x8];
+ u8 mkey_index[0x18];
+
+ u8 reserved_at_60[0x20];
+};
+
+struct mlx5_ifc_create_mkey_in_bits {
+ u8 opcode[0x10];
+ u8 reserved_at_10[0x10];
+
+ u8 reserved_at_20[0x10];
+ u8 op_mod[0x10];
+
+ u8 reserved_at_40[0x20];
+
+ u8 pg_access[0x1];
+ u8 mkey_umem_valid[0x1];
+ u8 reserved_at_62[0x1e];
+
+ struct mlx5_ifc_mkc_bits memory_key_mkey_entry;
+
+ u8 reserved_at_280[0x80];
+
+ u8 translations_octword_actual_size[0x20];
+
+ u8 reserved_at_320[0x560];
+
+ u8 klm_pas_mtt[0][0x20];
+};
@@ -168,6 +168,24 @@ enum mlx5dv_qp_create_flags {
MLX5DV_QP_CREATE_PACKET_BASED_CREDIT_MODE = 1 << 5,
};
+enum mlx5dv_mkey_init_attr_flags {
+ MLX5DV_MKEY_INIT_ATTR_FLAGS_INDIRECT = 1 << 0,
+};
+
+struct mlx5dv_mkey_init_attr {
+ struct ibv_pd *pd;
+ uint32_t create_flags; /* Use enum mlx5dv_mkey_init_attr_flags */
+ uint16_t max_entries; /* Requested max number of pointed entries by this indirect mkey */
+};
+
+struct mlx5dv_mkey {
+ uint32_t lkey;
+ uint32_t rkey;
+};
+
+struct mlx5dv_mkey *mlx5dv_create_mkey(struct mlx5dv_mkey_init_attr *mkey_init_attr);
+int mlx5dv_destroy_mkey(struct mlx5dv_mkey *mkey);
+
enum mlx5dv_qp_init_attr_mask {
MLX5DV_QP_INIT_ATTR_MASK_QP_CREATE_FLAGS = 1 << 0,
MLX5DV_QP_INIT_ATTR_MASK_DC = 1 << 1,
@@ -4500,3 +4500,64 @@ int mlx5dv_devx_get_async_cmd_comp(struct mlx5dv_devx_cmd_comp *cmd_comp,
return 0;
}
+struct mlx5dv_mkey *mlx5dv_create_mkey(struct mlx5dv_mkey_init_attr *mkey_init_attr)
+{
+ uint32_t out[DEVX_ST_SZ_DW(create_mkey_out)] = {};
+ uint32_t in[DEVX_ST_SZ_DW(create_mkey_in)] = {};
+ struct mlx5_mkey *mkey;
+ void *mkc;
+
+ if (!mkey_init_attr->create_flags ||
+ !check_comp_mask(mkey_init_attr->create_flags,
+ MLX5DV_MKEY_INIT_ATTR_FLAGS_INDIRECT)) {
+ errno = EOPNOTSUPP;
+ return NULL;
+ }
+
+ mkey = calloc(1, sizeof(*mkey));
+ if (!mkey) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ mkey->num_desc = align(mkey_init_attr->max_entries, 4);
+ DEVX_SET(create_mkey_in, in, opcode, MLX5_CMD_OP_CREATE_MKEY);
+ mkc = DEVX_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);
+ DEVX_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_KLMS);
+ DEVX_SET(mkc, mkc, free, 1);
+ DEVX_SET(mkc, mkc, umr_en, 1);
+ DEVX_SET(mkc, mkc, pd, to_mpd(mkey_init_attr->pd)->pdn);
+ DEVX_SET(mkc, mkc, translations_octword_size, mkey->num_desc);
+ DEVX_SET(mkc, mkc, lr, 1);
+ DEVX_SET(mkc, mkc, qpn, 0xffffff);
+ DEVX_SET(mkc, mkc, mkey_7_0, 0);
+
+ mkey->devx_obj = mlx5dv_devx_obj_create(mkey_init_attr->pd->context,
+ in, sizeof(in), out, sizeof(out));
+ if (!mkey->devx_obj)
+ goto end;
+
+ mkey_init_attr->max_entries = mkey->num_desc;
+ mkey->dv_mkey.lkey = (DEVX_GET(create_mkey_out, out, mkey_index) << 8) | 0;
+ mkey->dv_mkey.rkey = mkey->dv_mkey.lkey;
+
+ return &mkey->dv_mkey;
+end:
+ free(mkey);
+ return NULL;
+}
+
+int mlx5dv_destroy_mkey(struct mlx5dv_mkey *dv_mkey)
+{
+ struct mlx5_mkey *mkey = container_of(dv_mkey, struct mlx5_mkey,
+ dv_mkey);
+ int ret;
+
+ ret = mlx5dv_devx_obj_destroy(mkey->devx_obj);
+ if (ret)
+ return ret;
+
+ free(mkey);
+ return 0;
+}
+