1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2020 Mellanox Technologies, Ltd 3 */ 4 5 #include <unistd.h> 6 #include <string.h> 7 #include <stdio.h> 8 9 #include <rte_mempool.h> 10 #include <rte_malloc.h> 11 #include <rte_errno.h> 12 13 #include "mlx5_devx_cmds.h" 14 #include "../mlx5_common_log.h" 15 #include "mlx5_common.h" 16 #include "mlx5_common_os.h" 17 #include "mlx5_malloc.h" 18 19 /** 20 * Initialization routine for run-time dependency on external lib 21 */ 22 void 23 mlx5_glue_constructor(void) 24 { 25 } 26 27 /** 28 * Allocate PD. Given a devx context object 29 * return an mlx5-pd object. 30 * 31 * @param[in] ctx 32 * Pointer to context. 33 * 34 * @return 35 * The mlx5_pd if pd is valid, NULL and errno otherwise. 36 */ 37 void * 38 mlx5_os_alloc_pd(void *ctx) 39 { 40 struct mlx5_pd *ppd = mlx5_malloc(MLX5_MEM_ZERO, 41 sizeof(struct mlx5_pd), 0, SOCKET_ID_ANY); 42 if (!ppd) 43 return NULL; 44 45 struct mlx5_devx_obj *obj = mlx5_devx_cmd_alloc_pd(ctx); 46 if (!obj) { 47 mlx5_free(ppd); 48 return NULL; 49 } 50 ppd->obj = obj; 51 ppd->pdn = obj->id; 52 ppd->devx_ctx = ctx; 53 return ppd; 54 } 55 56 /** 57 * Release PD. Releases a given mlx5_pd object 58 * 59 * @param[in] pd 60 * Pointer to mlx5_pd. 61 * 62 * @return 63 * Zero if pd is released successfully, negative number otherwise. 64 */ 65 int 66 mlx5_os_dealloc_pd(void *pd) 67 { 68 if (!pd) 69 return -EINVAL; 70 mlx5_devx_cmd_destroy(((struct mlx5_pd *)pd)->obj); 71 mlx5_free(pd); 72 return 0; 73 } 74 75 /** 76 * Register umem. 77 * 78 * @param[in] ctx 79 * Pointer to context. 80 * @param[in] addr 81 * Pointer to memory start address. 82 * @param[in] size 83 * Size of the memory to register. 84 * @param[out] access 85 * UMEM access type 86 * 87 * @return 88 * umem on successful registration, NULL and errno otherwise 89 */ 90 void * 91 mlx5_os_umem_reg(void *ctx, void *addr, size_t size, uint32_t access) 92 { 93 struct mlx5_devx_umem *umem; 94 95 umem = mlx5_malloc(MLX5_MEM_ZERO, 96 (sizeof(*umem)), 0, SOCKET_ID_ANY); 97 if (!umem) { 98 errno = ENOMEM; 99 return NULL; 100 } 101 umem->umem_hdl = mlx5_glue->devx_umem_reg(ctx, addr, size, access, 102 &umem->umem_id); 103 if (!umem->umem_hdl) { 104 mlx5_free(umem); 105 return NULL; 106 } 107 umem->addr = addr; 108 return umem; 109 } 110 111 /** 112 * Deregister umem. 113 * 114 * @param[in] pumem 115 * Pointer to umem. 116 * 117 * @return 118 * 0 on successful release, negative number otherwise 119 */ 120 int 121 mlx5_os_umem_dereg(void *pumem) 122 { 123 struct mlx5_devx_umem *umem; 124 int err = 0; 125 126 if (!pumem) 127 return err; 128 umem = pumem; 129 if (umem->umem_hdl) 130 err = mlx5_glue->devx_umem_dereg(umem->umem_hdl); 131 mlx5_free(umem); 132 return err; 133 } 134 135 /** 136 * Register mr. Given protection doamin pointer, pointer to addr and length 137 * register the memory region. 138 * 139 * @param[in] pd 140 * Pointer to protection domain context (type mlx5_pd). 141 * @param[in] addr 142 * Pointer to memory start address (type devx_device_ctx). 143 * @param[in] length 144 * Lengtoh of the memory to register. 145 * @param[out] pmd_mr 146 * pmd_mr struct set with lkey, address, length, pointer to mr object, mkey 147 * 148 * @return 149 * 0 on successful registration, -1 otherwise 150 */ 151 int 152 mlx5_os_reg_mr(void *pd, 153 void *addr, size_t length, struct mlx5_pmd_mr *pmd_mr) 154 { 155 struct mlx5_devx_mkey_attr mkey_attr; 156 struct mlx5_pd *mlx5_pd = (struct mlx5_pd *)pd; 157 struct mlx5_hca_attr attr; 158 struct mlx5_devx_obj *mkey; 159 void *obj; 160 161 if (!pd || !addr) { 162 rte_errno = EINVAL; 163 return -1; 164 } 165 if (mlx5_devx_cmd_query_hca_attr(mlx5_pd->devx_ctx, &attr)) 166 return -1; 167 obj = mlx5_os_umem_reg(mlx5_pd->devx_ctx, addr, length, 168 IBV_ACCESS_LOCAL_WRITE); 169 if (!obj) 170 return -1; 171 memset(&mkey_attr, 0, sizeof(mkey_attr)); 172 mkey_attr.addr = (uintptr_t)addr; 173 mkey_attr.size = length; 174 mkey_attr.umem_id = ((struct mlx5_devx_umem *)(obj))->umem_id; 175 mkey_attr.pd = mlx5_pd->pdn; 176 if (!haswell_broadwell_cpu) { 177 mkey_attr.relaxed_ordering_write = attr.relaxed_ordering_write; 178 mkey_attr.relaxed_ordering_read = attr.relaxed_ordering_read; 179 } 180 mkey = mlx5_devx_cmd_mkey_create(mlx5_pd->devx_ctx, &mkey_attr); 181 if (!mkey) { 182 claim_zero(mlx5_os_umem_dereg(obj)); 183 return -1; 184 } 185 pmd_mr->addr = addr; 186 pmd_mr->len = length; 187 pmd_mr->obj = obj; 188 pmd_mr->mkey = mkey; 189 pmd_mr->lkey = pmd_mr->mkey->id; 190 return 0; 191 } 192 193 /** 194 * De-register mr. 195 * 196 * @param[in] pmd_mr 197 * Pointer to PMD mr object 198 */ 199 void 200 mlx5_os_dereg_mr(struct mlx5_pmd_mr *pmd_mr) 201 { 202 if (pmd_mr && pmd_mr->mkey) 203 claim_zero(mlx5_glue->devx_obj_destroy(pmd_mr->mkey->obj)); 204 if (pmd_mr && pmd_mr->obj) 205 claim_zero(mlx5_os_umem_dereg(pmd_mr->obj)); 206 memset(pmd_mr, 0, sizeof(*pmd_mr)); 207 } 208