]> git.droids-corp.org - dpdk.git/commitdiff
common/mlx5: create wrapped MR
authorMatan Azrad <matan@nvidia.com>
Tue, 9 Nov 2021 12:36:09 +0000 (14:36 +0200)
committerThomas Monjalon <thomas@monjalon.net>
Wed, 10 Nov 2021 14:48:56 +0000 (15:48 +0100)
The mlx5 PMD uses the kernel mlx5 driver to map physical memory to the
HW.

Using the Verbs API ibv_reg_mr, a mkey can be created for that.
In this case, the mkey is signed on the user ID of the kernel driver.

Using the DevX API, a mkey also can be created, but it should point an
umem object (represents the specific buffer mapping) created by the
kernel. In this case, the mkey is signed on the user ID of the process
DevX context.

In FW DevX control commands which get mkey as a parameter, there is
a security check on the user ID and Verbs mkeys are rejected.

Unfortunately, also when using DevX mkey, there is an error in the FW
command on umem validation because the umem is not designed to be used
for any mkey parameters.

As a workaround to the kernel driver/FW issue, it is needed to use a
wrapped MR, which is an indirect mkey(created by the DevX API) pointing to
direct mkey created by the kernel for any DevX command uses an MR.

Add an API to create and destroy this wrapped MR.

Fixes: 5382d28c2110 ("net/mlx5: accelerate DV flow counter transactions")
Fixes: 9d39e57f21ac ("vdpa/mlx5: support live migration")
Cc: stable@dpdk.org
Signed-off-by: Michael Baum <michaelba@nvidia.com>
Signed-off-by: Matan Azrad <matan@nvidia.com>
drivers/common/mlx5/linux/mlx5_common_os.c
drivers/common/mlx5/mlx5_common.h
drivers/common/mlx5/version.map
drivers/common/mlx5/windows/mlx5_common_os.c

index b516564b79465b2a519f4c4e6788a9910542e161..0d3e24e04e39e5912baea230941903bbdb99dfd2 100644 (file)
@@ -744,3 +744,59 @@ mlx5_get_device_guid(const struct rte_pci_addr *dev, uint8_t *guid, size_t len)
        fclose(id_file);
        return ret;
 }
+
+/*
+ * Create direct mkey using the kernel ibv_reg_mr API and wrap it with a new
+ * indirect mkey created by the DevX API.
+ * This mkey should be used for DevX commands requesting mkey as a parameter.
+ */
+int
+mlx5_os_wrapped_mkey_create(void *ctx, void *pd, uint32_t pdn, void *addr,
+                           size_t length, struct mlx5_pmd_wrapped_mr *pmd_mr)
+{
+       struct mlx5_klm klm = {
+               .byte_count = length,
+               .address = (uintptr_t)addr,
+       };
+       struct mlx5_devx_mkey_attr mkey_attr = {
+               .pd = pdn,
+               .klm_array = &klm,
+               .klm_num = 1,
+       };
+       struct mlx5_devx_obj *mkey;
+       struct ibv_mr *ibv_mr = mlx5_glue->reg_mr(pd, addr, length,
+                                                 IBV_ACCESS_LOCAL_WRITE |
+                                                 (haswell_broadwell_cpu ? 0 :
+                                                 IBV_ACCESS_RELAXED_ORDERING));
+
+       if (!ibv_mr) {
+               rte_errno = errno;
+               return -rte_errno;
+       }
+       klm.mkey = ibv_mr->lkey;
+       mkey_attr.addr = (uintptr_t)addr;
+       mkey_attr.size = length;
+       mkey = mlx5_devx_cmd_mkey_create(ctx, &mkey_attr);
+       if (!mkey) {
+               claim_zero(mlx5_glue->dereg_mr(ibv_mr));
+               return -rte_errno;
+       }
+       pmd_mr->addr = addr;
+       pmd_mr->len = length;
+       pmd_mr->obj = (void *)ibv_mr;
+       pmd_mr->imkey = mkey;
+       pmd_mr->lkey = mkey->id;
+       return 0;
+}
+
+void
+mlx5_os_wrapped_mkey_destroy(struct mlx5_pmd_wrapped_mr *pmd_mr)
+{
+       if (!pmd_mr)
+               return;
+       if (pmd_mr->imkey)
+               claim_zero(mlx5_devx_cmd_destroy(pmd_mr->imkey));
+       if (pmd_mr->obj)
+               claim_zero(mlx5_glue->dereg_mr(pmd_mr->obj));
+       memset(pmd_mr, 0, sizeof(*pmd_mr));
+}
index 661d3ab235b531801bfc490cf4d3d5c373c9b212..e8809844afadd2f9f7283050c152b7eff2c1873c 100644 (file)
@@ -509,4 +509,22 @@ mlx5_devx_uar_release(struct mlx5_uar *uar);
 int mlx5_os_open_device(struct mlx5_common_device *cdev, uint32_t classes);
 int mlx5_os_pd_create(struct mlx5_common_device *cdev);
 
+/* mlx5 PMD wrapped MR struct. */
+struct mlx5_pmd_wrapped_mr {
+       uint32_t             lkey;
+       void                 *addr;
+       size_t               len;
+       void                 *obj; /* verbs mr object or devx umem object. */
+       void                 *imkey; /* DevX indirect mkey object. */
+};
+
+__rte_internal
+int
+mlx5_os_wrapped_mkey_create(void *ctx, void *pd, uint32_t pdn, void *addr,
+                           size_t length, struct mlx5_pmd_wrapped_mr *pmd_mr);
+
+__rte_internal
+void
+mlx5_os_wrapped_mkey_destroy(struct mlx5_pmd_wrapped_mr *pmd_mr);
+
 #endif /* RTE_PMD_MLX5_COMMON_H_ */
index 2335edf39db3edc96aa078aa1feba9268fac84ed..8a62dc27823380841e3b80e0496c31c5aaadda4d 100644 (file)
@@ -134,6 +134,9 @@ INTERNAL {
        mlx5_os_umem_dereg;
        mlx5_os_umem_reg;
 
+       mlx5_os_wrapped_mkey_create;
+       mlx5_os_wrapped_mkey_destroy;
+
        mlx5_realloc;
 
        mlx5_translate_port_name; # WINDOWS_NO_EXPORT
index ea478d73958e97b6ae0c6cd5ead4fbb562ebabe1..5fb45d12ea5b59941bd464b239e15809be73805b 100644 (file)
@@ -390,3 +390,42 @@ mlx5_os_set_reg_mr_cb(mlx5_reg_mr_t *reg_mr_cb, mlx5_dereg_mr_t *dereg_mr_cb)
        *reg_mr_cb = mlx5_os_reg_mr;
        *dereg_mr_cb = mlx5_os_dereg_mr;
 }
+
+/*
+ * In Windows, no need to wrap the MR, no known issue for it in kernel.
+ * Use the regular function to create direct MR.
+ */
+int
+mlx5_os_wrapped_mkey_create(void *ctx, void *pd, uint32_t pdn, void *addr,
+                           size_t length, struct mlx5_pmd_wrapped_mr *wpmd_mr)
+{
+       struct mlx5_pmd_mr pmd_mr = {0};
+       int ret = mlx5_os_reg_mr(pd, addr, length, &pmd_mr);
+
+       (void)pdn;
+       (void)ctx;
+       if (ret != 0)
+               return -1;
+       wpmd_mr->addr = addr;
+       wpmd_mr->len = length;
+       wpmd_mr->obj = pmd_mr.obj;
+       wpmd_mr->imkey = pmd_mr.mkey;
+       wpmd_mr->lkey = pmd_mr.mkey->id;
+       return 0;
+}
+
+void
+mlx5_os_wrapped_mkey_destroy(struct mlx5_pmd_wrapped_mr *wpmd_mr)
+{
+       struct mlx5_pmd_mr pmd_mr;
+
+       if (!wpmd_mr)
+               return;
+       pmd_mr.addr = wpmd_mr->addr;
+       pmd_mr.len = wpmd_mr->len;
+       pmd_mr.obj = wpmd_mr->obj;
+       pmd_mr.mkey = wpmd_mr->imkey;
+       pmd_mr.lkey = wpmd_mr->lkey;
+       mlx5_os_dereg_mr(&pmd_mr);
+       memset(wpmd_mr, 0, sizeof(*wpmd_mr));
+}