xref: /dpdk/drivers/common/mlx5/windows/mlx5_common_os.c (revision bbbe38a6d59ccdda25917712701e629d0b10af6f)
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