#include "mlx5_common_os.h"
#include "mlx5_common_utils.h"
#include "mlx5_malloc.h"
+#include "mlx5_common_pci.h"
int mlx5_common_logtype;
uint8_t haswell_broadwell_cpu;
-static int
-mlx5_class_check_handler(__rte_unused const char *key, const char *value,
- void *opaque)
-{
- enum mlx5_class *ret = opaque;
-
- if (strcmp(value, "vdpa") == 0) {
- *ret = MLX5_CLASS_VDPA;
- } else if (strcmp(value, "net") == 0) {
- *ret = MLX5_CLASS_NET;
- } else {
- DRV_LOG(ERR, "Invalid mlx5 class %s. Maybe typo in device"
- " class argument setting?", value);
- *ret = MLX5_CLASS_INVALID;
- }
- return 0;
-}
-
-enum mlx5_class
-mlx5_class_get(struct rte_devargs *devargs)
-{
- struct rte_kvargs *kvlist;
- const char *key = MLX5_CLASS_ARG_NAME;
- enum mlx5_class ret = MLX5_CLASS_NET;
-
- if (devargs == NULL)
- return ret;
- kvlist = rte_kvargs_parse(devargs->args, NULL);
- if (kvlist == NULL)
- return ret;
- if (rte_kvargs_count(kvlist, key))
- rte_kvargs_process(kvlist, key, mlx5_class_check_handler, &ret);
- rte_kvargs_free(kvlist);
- return ret;
-}
-
-
/* In case this is an x86_64 intel processor to check if
* we should use relaxed ordering.
*/
return;
mlx5_glue_constructor();
+ mlx5_common_pci_init();
mlx5_common_initialized = true;
}
return NULL;
}
/* Register allocated memory. */
- page->umem = mlx5_glue->devx_umem_reg(ctx, page->dbrs,
+ page->umem = mlx5_os_umem_reg(ctx, page->dbrs,
MLX5_DBR_PAGE_SIZE, 0);
if (!page->umem) {
DRV_LOG(ERR, "cannot umem reg dbr page");
page->dbr_bitmap[i] |= (UINT64_C(1) << j);
page->dbr_count++;
*dbr_page = page;
- return (((i * 64) + j) * sizeof(uint64_t));
+ return (i * CHAR_BIT * sizeof(uint64_t) + j) * MLX5_DBR_SIZE;
}
/**
/* Page not used, free it and remove from list. */
LIST_REMOVE(page, next);
if (page->umem)
- ret = -mlx5_glue->devx_umem_dereg(page->umem);
+ ret = -mlx5_os_umem_dereg(page->umem);
mlx5_free(page);
} else {
/* Mark in bitmap that this door-bell is not in use. */
}
return ret;
}
+
+/**
+ * Allocate the User Access Region with DevX on specified device.
+ *
+ * @param [in] ctx
+ * Infiniband device context to perform allocation on.
+ * @param [in] mapping
+ * MLX5DV_UAR_ALLOC_TYPE_BF - allocate as cached memory with write-combining
+ * attributes (if supported by the host), the
+ * writes to the UAR registers must be followed
+ * by write memory barrier.
+ * MLX5DV_UAR_ALLOC_TYPE_NC - allocate as non-cached nenory, all writes are
+ * promoted to the registers immediately, no
+ * memory barriers needed.
+ * mapping < 0 - the first attempt is performed with MLX5DV_UAR_ALLOC_TYPE_BF,
+ * if this fails the next attempt with MLX5DV_UAR_ALLOC_TYPE_NC
+ * is performed. The drivers specifying negative values should
+ * always provide the write memory barrier operation after UAR
+ * register writings.
+ * If there is no definitions for the MLX5DV_UAR_ALLOC_TYPE_xx (older rdma
+ * library headers), the caller can specify 0.
+ *
+ * @return
+ * UAR object pointer on success, NULL otherwise and rte_errno is set.
+ */
+void *
+mlx5_devx_alloc_uar(void *ctx, int mapping)
+{
+ void *uar;
+ uint32_t retry, uar_mapping;
+ void *base_addr;
+
+ for (retry = 0; retry < MLX5_ALLOC_UAR_RETRY; ++retry) {
+#ifdef MLX5DV_UAR_ALLOC_TYPE_NC
+ /* Control the mapping type according to the settings. */
+ uar_mapping = (mapping < 0) ?
+ MLX5DV_UAR_ALLOC_TYPE_NC : mapping;
+#else
+ /*
+ * It seems we have no way to control the memory mapping type
+ * for the UAR, the default "Write-Combining" type is supposed.
+ */
+ uar_mapping = 0;
+ RTE_SET_USED(mapping);
+#endif
+ uar = mlx5_glue->devx_alloc_uar(ctx, uar_mapping);
+#ifdef MLX5DV_UAR_ALLOC_TYPE_NC
+ if (!uar &&
+ mapping < 0 &&
+ uar_mapping == MLX5DV_UAR_ALLOC_TYPE_BF) {
+ /*
+ * In some environments like virtual machine the
+ * Write Combining mapped might be not supported and
+ * UAR allocation fails. We tried "Non-Cached" mapping
+ * for the case.
+ */
+ DRV_LOG(WARNING, "Failed to allocate DevX UAR (BF)");
+ uar_mapping = MLX5DV_UAR_ALLOC_TYPE_NC;
+ uar = mlx5_glue->devx_alloc_uar(ctx, uar_mapping);
+ } else if (!uar &&
+ mapping < 0 &&
+ uar_mapping == MLX5DV_UAR_ALLOC_TYPE_NC) {
+ /*
+ * If Verbs/kernel does not support "Non-Cached"
+ * try the "Write-Combining".
+ */
+ DRV_LOG(WARNING, "Failed to allocate DevX UAR (NC)");
+ uar_mapping = MLX5DV_UAR_ALLOC_TYPE_BF;
+ uar = mlx5_glue->devx_alloc_uar(ctx, uar_mapping);
+ }
+#endif
+ if (!uar) {
+ DRV_LOG(ERR, "Failed to allocate DevX UAR (BF/NC)");
+ rte_errno = ENOMEM;
+ goto exit;
+ }
+ base_addr = mlx5_os_get_devx_uar_base_addr(uar);
+ if (base_addr)
+ break;
+ /*
+ * The UARs are allocated by rdma_core within the
+ * IB device context, on context closure all UARs
+ * will be freed, should be no memory/object leakage.
+ */
+ DRV_LOG(WARNING, "Retrying to allocate DevX UAR");
+ uar = NULL;
+ }
+ /* Check whether we finally succeeded with valid UAR allocation. */
+ if (!uar) {
+ DRV_LOG(ERR, "Failed to allocate DevX UAR (NULL base)");
+ rte_errno = ENOMEM;
+ }
+ /*
+ * Return void * instead of struct mlx5dv_devx_uar *
+ * is for compatibility with older rdma-core library headers.
+ */
+exit:
+ return uar;
+}