From: Michael Baum <michae...@nvidia.com>

Add option to probe common device using import CTX/PD functions instead
of create functions.
This option requires accepting the context FD and the PD handle as
devargs.

Signed-off-by: Michael Baum <michae...@nvidia.com>
---
 drivers/common/mlx5/linux/mlx5_common_os.c   | 160 +++++++++++++++++--
 drivers/common/mlx5/linux/mlx5_common_os.h   |   6 -
 drivers/common/mlx5/mlx5_common.c            |  32 ++--
 drivers/common/mlx5/mlx5_common.h            |   6 +-
 drivers/common/mlx5/windows/mlx5_common_os.c |  29 +++-
 drivers/common/mlx5/windows/mlx5_common_os.h |   1 -
 6 files changed, 196 insertions(+), 38 deletions(-)

diff --git a/drivers/common/mlx5/linux/mlx5_common_os.c 
b/drivers/common/mlx5/linux/mlx5_common_os.c
index 0d3e24e04e..a8226e987f 100644
--- a/drivers/common/mlx5/linux/mlx5_common_os.c
+++ b/drivers/common/mlx5/linux/mlx5_common_os.c
@@ -416,7 +416,7 @@ mlx5_glue_constructor(void)
  * @return
  *   0 on success, a negative errno value otherwise and rte_errno is set.
  */
-int
+static int
 mlx5_os_pd_create(struct mlx5_common_device *cdev)
 {
 #ifdef HAVE_IBV_FLOW_DV_SUPPORT
@@ -450,6 +450,65 @@ mlx5_os_pd_create(struct mlx5_common_device *cdev)
 #endif /* HAVE_IBV_FLOW_DV_SUPPORT */
 }
 
+/**
+ * Import Protection Domain object according to given pdn.
+ *
+ * @param[out] cdev
+ *   Pointer to the mlx5 device.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_os_pd_import(struct mlx5_common_device *cdev)
+{
+       struct mlx5_common_dev_config *config = &cdev->config;
+
+       cdev->pd = mlx5_glue->import_pd(cdev->ctx, config->pd_handle);
+       if (cdev->pd == NULL) {
+               DRV_LOG(ERR, "Failed to import PD.");
+               return errno ? -errno : -ENOMEM;
+       }
+       cdev->pdn = config->pd_handle;
+       return 0;
+}
+
+/**
+ * Prepare Protection Domain object and extract its pdn using DV API.
+ *
+ * @param[out] cdev
+ *   Pointer to the mlx5 device.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_os_pd_prepare(struct mlx5_common_device *cdev)
+{
+       if (cdev->config.pd_handle == MLX5_ARG_UNSET)
+               return mlx5_os_pd_create(cdev);
+       else
+               return mlx5_os_pd_import(cdev);
+}
+
+/**
+ * Release Protection Domain object.
+ *
+ * @param[out] cdev
+ *   Pointer to the mlx5 device.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise.
+ */
+int
+mlx5_os_pd_release(struct mlx5_common_device *cdev)
+{
+       if (cdev->config.pd_handle == MLX5_ARG_UNSET)
+               return mlx5_glue->dealloc_pd(cdev->pd);
+       mlx5_glue->unimport_pd(cdev->pd);
+       return 0;
+}
+
 static struct ibv_device *
 mlx5_os_get_ibv_device(const struct rte_pci_addr *addr)
 {
@@ -648,28 +707,28 @@ mlx5_restore_doorbell_mapping_env(int value)
 /**
  * Function API to open IB device.
  *
- *
  * @param cdev
  *   Pointer to the mlx5 device.
  * @param classes
  *   Chosen classes come from device arguments.
  *
  * @return
- *   0 on success, a negative errno value otherwise and rte_errno is set.
+ *   Pointer to ibv_context on success, NULL otherwise and rte_errno is set.
  */
-int
-mlx5_os_open_device(struct mlx5_common_device *cdev, uint32_t classes)
+static struct ibv_context *
+mlx5_open_device(struct mlx5_common_device *cdev, uint32_t classes)
 {
        struct ibv_device *ibv;
        struct ibv_context *ctx = NULL;
        int dbmap_env;
 
+       MLX5_ASSERT(cdev->config.device_fd == MLX5_ARG_UNSET);
        if (classes & MLX5_CLASS_VDPA)
                ibv = mlx5_vdpa_get_ibv_dev(cdev->dev);
        else
                ibv = mlx5_os_get_ibv_dev(cdev->dev);
        if (!ibv)
-               return -rte_errno;
+               return NULL;
        DRV_LOG(INFO, "Dev information matches for device \"%s\".", ibv->name);
        /*
         * Configure environment variable "MLX5_BF_SHUT_UP" before the device
@@ -682,29 +741,104 @@ mlx5_os_open_device(struct mlx5_common_device *cdev, 
uint32_t classes)
        ctx = mlx5_glue->dv_open_device(ibv);
        if (ctx) {
                cdev->config.devx = 1;
-               DRV_LOG(DEBUG, "DevX is supported.");
        } else if (classes == MLX5_CLASS_ETH) {
                /* The environment variable is still configured. */
                ctx = mlx5_glue->open_device(ibv);
                if (ctx == NULL)
                        goto error;
-               DRV_LOG(DEBUG, "DevX is NOT supported.");
        } else {
                goto error;
        }
        /* The device is created, no need for environment. */
        mlx5_restore_doorbell_mapping_env(dbmap_env);
-       /* Hint libmlx5 to use PMD allocator for data plane resources */
-       mlx5_set_context_attr(cdev->dev, ctx);
-       cdev->ctx = ctx;
-       return 0;
+       return ctx;
 error:
        rte_errno = errno ? errno : ENODEV;
        /* The device creation is failed, no need for environment. */
        mlx5_restore_doorbell_mapping_env(dbmap_env);
        DRV_LOG(ERR, "Failed to open IB device \"%s\".", ibv->name);
-       return -rte_errno;
+       return NULL;
 }
+
+/**
+ * Function API to import IB device.
+ *
+ * @param cdev
+ *   Pointer to the mlx5 device.
+ *
+ * @return
+ *   Pointer to ibv_context on success, NULL otherwise and rte_errno is set.
+ */
+static struct ibv_context *
+mlx5_import_device(struct mlx5_common_device *cdev)
+{
+       struct ibv_context *ctx = NULL;
+
+       MLX5_ASSERT(cdev->config.device_fd != MLX5_ARG_UNSET);
+       ctx = mlx5_glue->import_device(cdev->config.device_fd);
+       if (!ctx) {
+               DRV_LOG(ERR, "Failed to import device for fd=%d.",
+                       cdev->config.device_fd);
+               rte_errno = errno;
+       }
+       return ctx;
+}
+
+/**
+ * Function API to prepare IB device.
+ *
+ * @param cdev
+ *   Pointer to the mlx5 device.
+ * @param classes
+ *   Chosen classes come from device arguments.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+int
+mlx5_os_open_device(struct mlx5_common_device *cdev, uint32_t classes)
+{
+
+       struct ibv_context *ctx = NULL;
+
+       if (cdev->config.device_fd == MLX5_ARG_UNSET)
+               ctx = mlx5_open_device(cdev, classes);
+       else
+               ctx = mlx5_import_device(cdev);
+       if (ctx == NULL)
+               return -rte_errno;
+       /* Hint libmlx5 to use PMD allocator for data plane resources */
+       mlx5_set_context_attr(cdev->dev, ctx);
+       cdev->ctx = ctx;
+       return 0;
+}
+
+/**
+ * Query HCA attributes.
+ * For remote context, it is check if DevX is supported.
+ *
+ * @param cdev
+ *   Pointer to mlx5 device structure.
+ *
+ * @return
+ *   0 on success, a negative value otherwise.
+ */
+int
+mlx5_os_query_hca_attr(struct mlx5_common_device *cdev)
+{
+       int ret;
+
+       ret = mlx5_devx_cmd_query_hca_attr(cdev->ctx, &cdev->config.hca_attr);
+       if (ret) {
+               if (cdev->config.device_fd == MLX5_ARG_UNSET) {
+                       rte_errno = ENOTSUP;
+                       return -rte_errno;
+               }
+               cdev->config.devx = 0;
+       }
+       return 0;
+}
+
 int
 mlx5_get_device_guid(const struct rte_pci_addr *dev, uint8_t *guid, size_t len)
 {
diff --git a/drivers/common/mlx5/linux/mlx5_common_os.h 
b/drivers/common/mlx5/linux/mlx5_common_os.h
index 83066e752d..246e8b2784 100644
--- a/drivers/common/mlx5/linux/mlx5_common_os.h
+++ b/drivers/common/mlx5/linux/mlx5_common_os.h
@@ -203,12 +203,6 @@ mlx5_os_get_devx_uar_page_id(void *uar)
 #endif
 }
 
-static inline int
-mlx5_os_dealloc_pd(void *pd)
-{
-       return mlx5_glue->dealloc_pd(pd);
-}
-
 __rte_internal
 static inline void *
 mlx5_os_umem_reg(void *ctx, void *addr, size_t size, uint32_t access)
diff --git a/drivers/common/mlx5/mlx5_common.c 
b/drivers/common/mlx5/mlx5_common.c
index f1650f94c6..bd7f0021d5 100644
--- a/drivers/common/mlx5/mlx5_common.c
+++ b/drivers/common/mlx5/mlx5_common.c
@@ -133,6 +133,10 @@ mlx5_common_args_check_handler(const char *key, const char 
*val, void *opaque)
                config->mr_mempool_reg_en = !!tmp;
        } else if (strcmp(key, "sys_mem_en") == 0) {
                config->sys_mem_en = !!tmp;
+       } else if (strcmp(key, "device_fd") == 0) {
+               config->device_fd = !!tmp;
+       } else if (strcmp(key, "pd_handle") == 0) {
+               config->pd_handle = !!tmp;
        }
        return 0;
 }
@@ -160,6 +164,8 @@ mlx5_common_config_get(struct rte_devargs *devargs,
        config->mr_mempool_reg_en = 1;
        config->sys_mem_en = 0;
        config->dbnc = MLX5_ARG_UNSET;
+       config->device_fd = MLX5_ARG_UNSET;
+       config->pd_handle = MLX5_ARG_UNSET;
        if (devargs == NULL)
                return 0;
        kvlist = rte_kvargs_parse(devargs->args, NULL);
@@ -492,7 +498,7 @@ static void
 mlx5_dev_hw_global_release(struct mlx5_common_device *cdev)
 {
        if (cdev->pd != NULL) {
-               claim_zero(mlx5_os_dealloc_pd(cdev->pd));
+               claim_zero(mlx5_os_pd_release(cdev));
                cdev->pd = NULL;
        }
        if (cdev->ctx != NULL) {
@@ -522,19 +528,23 @@ mlx5_dev_hw_global_prepare(struct mlx5_common_device 
*cdev, uint32_t classes)
        if (ret < 0)
                return ret;
        /* Allocate Protection Domain object and extract its pdn. */
-       ret = mlx5_os_pd_create(cdev);
+       ret = mlx5_os_pd_prepare(cdev);
        if (ret)
                goto error;
-       /* All actions taken below are relevant only when DevX is supported */
-       if (cdev->config.devx == 0)
-               return 0;
-       /* Query HCA attributes. */
-       ret = mlx5_devx_cmd_query_hca_attr(cdev->ctx, &cdev->config.hca_attr);
-       if (ret) {
-               DRV_LOG(ERR, "Unable to read HCA capabilities.");
-               rte_errno = ENOTSUP;
-               goto error;
+       /*
+        * TODO: write it again...
+        * All actions taken below are relevant only when DevX is supported
+        */
+       if (cdev->config.devx || cdev->config.device_fd != MLX5_ARG_UNSET) {
+               /* Query HCA attributes. */
+               ret = mlx5_os_query_hca_attr(cdev);
+               if (ret) {
+                       DRV_LOG(ERR, "Unable to read HCA capabilities.");
+                       rte_errno = ENOTSUP;
+                       goto error;
+               }
        }
+       DRV_LOG(DEBUG, "DevX is %ssupported.", cdev->config.devx ? "" : "NOT ");
        return 0;
 error:
        mlx5_dev_hw_global_release(cdev);
diff --git a/drivers/common/mlx5/mlx5_common.h 
b/drivers/common/mlx5/mlx5_common.h
index e8809844af..78c8a29740 100644
--- a/drivers/common/mlx5/mlx5_common.h
+++ b/drivers/common/mlx5/mlx5_common.h
@@ -414,6 +414,8 @@ void mlx5_common_init(void);
 struct mlx5_common_dev_config {
        struct mlx5_hca_attr hca_attr; /* HCA attributes. */
        int dbnc; /* Skip doorbell register write barrier. */
+       int device_fd; /* Device file descriptor for importation. */
+       int pd_handle; /* Protection Domain handle for importation.  */
        unsigned int devx:1; /* Whether devx interface is available or not. */
        unsigned int sys_mem_en:1; /* The default memory allocator. */
        unsigned int mr_mempool_reg_en:1;
@@ -507,7 +509,9 @@ mlx5_devx_uar_release(struct mlx5_uar *uar);
 /* mlx5_common_os.c */
 
 int mlx5_os_open_device(struct mlx5_common_device *cdev, uint32_t classes);
-int mlx5_os_pd_create(struct mlx5_common_device *cdev);
+int mlx5_os_query_hca_attr(struct mlx5_common_device *cdev);
+int mlx5_os_pd_prepare(struct mlx5_common_device *cdev);
+int mlx5_os_pd_release(struct mlx5_common_device *cdev);
 
 /* mlx5 PMD wrapped MR struct. */
 struct mlx5_pmd_wrapped_mr {
diff --git a/drivers/common/mlx5/windows/mlx5_common_os.c 
b/drivers/common/mlx5/windows/mlx5_common_os.c
index 162c7476cc..d8410f57c1 100644
--- a/drivers/common/mlx5/windows/mlx5_common_os.c
+++ b/drivers/common/mlx5/windows/mlx5_common_os.c
@@ -25,21 +25,38 @@ mlx5_glue_constructor(void)
 {
 }
 
+/**
+ * Query HCA attributes.
+ *
+ * @param cdev
+ *   Pointer to mlx5 device structure.
+ *
+ * @return
+ *   0 on success, a negative value otherwise.
+ */
+int
+mlx5_os_query_hca_attr(struct mlx5_common_device *cdev)
+{
+       return mlx5_devx_cmd_query_hca_attr(cdev->ctx, &cdev->config.hca_attr);
+}
+
 /**
  * Release PD. Releases a given mlx5_pd object
  *
- * @param[in] pd
- *   Pointer to mlx5_pd.
+ * @param[in] cdev
+ *   Pointer to the mlx5 device.
  *
  * @return
  *   Zero if pd is released successfully, negative number otherwise.
  */
 int
-mlx5_os_dealloc_pd(void *pd)
+mlx5_os_pd_release(struct mlx5_common_device *cdev)
 {
+       struct mlx5_pd *pd = cdev->pd;
+
        if (!pd)
                return -EINVAL;
-       mlx5_devx_cmd_destroy(((struct mlx5_pd *)pd)->obj);
+       mlx5_devx_cmd_destroy(pd->obj);
        mlx5_free(pd);
        return 0;
 }
@@ -47,14 +64,14 @@ mlx5_os_dealloc_pd(void *pd)
 /**
  * Allocate Protection Domain object and extract its pdn using DV API.
  *
- * @param[out] dev
+ * @param[out] cdev
  *   Pointer to the mlx5 device.
  *
  * @return
  *   0 on success, a negative value otherwise.
  */
 int
-mlx5_os_pd_create(struct mlx5_common_device *cdev)
+mlx5_os_pd_prepare(struct mlx5_common_device *cdev)
 {
        struct mlx5_pd *pd;
 
diff --git a/drivers/common/mlx5/windows/mlx5_common_os.h 
b/drivers/common/mlx5/windows/mlx5_common_os.h
index 3afce56cd9..a6a1b6890f 100644
--- a/drivers/common/mlx5/windows/mlx5_common_os.h
+++ b/drivers/common/mlx5/windows/mlx5_common_os.h
@@ -248,7 +248,6 @@ mlx5_os_devx_subscribe_devx_event(void *eventc,
        return -ENOTSUP;
 }
 
-int mlx5_os_dealloc_pd(void *pd);
 __rte_internal
 void *mlx5_os_umem_reg(void *ctx, void *addr, size_t size, uint32_t access);
 __rte_internal
-- 
2.25.1

Reply via email to