/* SPDX-License-Identifier: BSD-3-Clause * Copyright 2020 Mellanox Technologies, Ltd */ #include #include #include #include #include #include #include "mlx5_devx_cmds.h" #include "mlx5_common_utils.h" #include "mlx5_common.h" #include "mlx5_common_os.h" #include "mlx5_malloc.h" /** * Initialization routine for run-time dependency on external lib */ void mlx5_glue_constructor(void) { } /** * Allocate PD. Given a devx context object * return an mlx5-pd object. * * @param[in] ctx * Pointer to context. * * @return * The mlx5_pd if pd is valid, NULL and errno otherwise. */ void * mlx5_os_alloc_pd(void *ctx) { struct mlx5_pd *ppd = mlx5_malloc(MLX5_MEM_ZERO, sizeof(struct mlx5_pd), 0, SOCKET_ID_ANY); if (!ppd) return NULL; struct mlx5_devx_obj *obj = mlx5_devx_cmd_alloc_pd(ctx); if (!obj) { mlx5_free(ppd); return NULL; } ppd->obj = obj; ppd->pdn = obj->id; ppd->devx_ctx = ctx; return ppd; } /** * Release PD. Releases a given mlx5_pd object * * @param[in] pd * Pointer to mlx5_pd. * * @return * Zero if pd is released successfully, negative number otherwise. */ int mlx5_os_dealloc_pd(void *pd) { if (!pd) return -EINVAL; mlx5_devx_cmd_destroy(((struct mlx5_pd *)pd)->obj); mlx5_free(pd); return 0; } /** * Register umem. * * @param[in] ctx * Pointer to context. * @param[in] addr * Pointer to memory start address. * @param[in] size * Size of the memory to register. * @param[out] access * UMEM access type * * @return * umem on successful registration, NULL and errno otherwise */ void * mlx5_os_umem_reg(void *ctx, void *addr, size_t size, uint32_t access) { struct mlx5_devx_umem *umem; umem = mlx5_malloc(MLX5_MEM_ZERO, (sizeof(*umem)), 0, SOCKET_ID_ANY); if (!umem) { errno = ENOMEM; return NULL; } umem->umem_hdl = mlx5_glue->devx_umem_reg(ctx, addr, size, access, &umem->umem_id); if (!umem->umem_hdl) { mlx5_free(umem); return NULL; } umem->addr = addr; return umem; } /** * Deregister umem. * * @param[in] pumem * Pointer to umem. * * @return * 0 on successful release, negative number otherwise */ int mlx5_os_umem_dereg(void *pumem) { struct mlx5_devx_umem *umem; int err = 0; if (!pumem) return err; umem = pumem; if (umem->umem_hdl) err = mlx5_glue->devx_umem_dereg(umem->umem_hdl); mlx5_free(umem); return err; } /** * Register mr. Given protection doamin pointer, pointer to addr and length * register the memory region. * * @param[in] pd * Pointer to protection domain context (type mlx5_pd). * @param[in] addr * Pointer to memory start address (type devx_device_ctx). * @param[in] length * Lengtoh of the memory to register. * @param[out] pmd_mr * pmd_mr struct set with lkey, address, length, pointer to mr object, mkey * * @return * 0 on successful registration, -1 otherwise */ int mlx5_os_reg_mr(void *pd, void *addr, size_t length, struct mlx5_pmd_mr *pmd_mr) { struct mlx5_devx_mkey_attr mkey_attr; struct mlx5_pd *mlx5_pd = (struct mlx5_pd *)pd; struct mlx5_hca_attr attr; if (!pd || !addr) { rte_errno = EINVAL; return -1; } memset(pmd_mr, 0, sizeof(*pmd_mr)); if (mlx5_devx_cmd_query_hca_attr(mlx5_pd->devx_ctx, &attr)) return -1; pmd_mr->addr = addr; pmd_mr->len = length; pmd_mr->obj = mlx5_os_umem_reg(mlx5_pd->devx_ctx, pmd_mr->addr, pmd_mr->len, IBV_ACCESS_LOCAL_WRITE); if (!pmd_mr->obj) return -1; mkey_attr.addr = (uintptr_t)addr; mkey_attr.size = length; mkey_attr.umem_id = ((struct mlx5_devx_umem *)(pmd_mr->obj))->umem_id; mkey_attr.pd = mlx5_pd->pdn; mkey_attr.log_entity_size = 0; mkey_attr.pg_access = 0; mkey_attr.klm_array = NULL; mkey_attr.klm_num = 0; mkey_attr.relaxed_ordering_read = 0; mkey_attr.relaxed_ordering_write = 0; if (!haswell_broadwell_cpu) { mkey_attr.relaxed_ordering_write = attr.relaxed_ordering_write; mkey_attr.relaxed_ordering_read = attr.relaxed_ordering_read; } pmd_mr->mkey = mlx5_devx_cmd_mkey_create(mlx5_pd->devx_ctx, &mkey_attr); if (!pmd_mr->mkey) { claim_zero(mlx5_os_umem_dereg(pmd_mr->obj)); return -1; } pmd_mr->lkey = pmd_mr->mkey->id; return 0; } /** * De-register mr. * * @param[in] pmd_mr * Pointer to PMD mr object */ void mlx5_os_dereg_mr(struct mlx5_pmd_mr *pmd_mr) { if (pmd_mr && pmd_mr->mkey) claim_zero(mlx5_glue->devx_obj_destroy(pmd_mr->mkey->obj)); if (pmd_mr && pmd_mr->obj) claim_zero(mlx5_os_umem_dereg(pmd_mr->obj)); memset(pmd_mr, 0, sizeof(*pmd_mr)); }