Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright 2019 6WIND S.A.
3 : : * Copyright 2019 Mellanox Technologies, Ltd
4 : : */
5 : :
6 : : #include <stdio.h>
7 : : #include <time.h>
8 : :
9 : : #include <eal_export.h>
10 : : #include <rte_eal.h>
11 : : #include <rte_errno.h>
12 : :
13 : : #include "mlx5_common_mp.h"
14 : : #include "mlx5_common_log.h"
15 : : #include "mlx5_malloc.h"
16 : :
17 : : /**
18 : : * Request Memory Region creation to the primary process.
19 : : *
20 : : * @param cdev
21 : : * Pointer to the mlx5 common device.
22 : : * @param addr
23 : : * Target virtual address to register.
24 : : *
25 : : * @return
26 : : * 0 on success, a negative errno value otherwise and rte_errno is set.
27 : : */
28 : : RTE_EXPORT_INTERNAL_SYMBOL(mlx5_mp_req_mr_create)
29 : : int
30 : 0 : mlx5_mp_req_mr_create(struct mlx5_common_device *cdev, uintptr_t addr)
31 : : {
32 : : struct rte_mp_msg mp_req;
33 : : struct rte_mp_msg *mp_res;
34 : : struct rte_mp_reply mp_rep;
35 : : struct mlx5_mp_param *req = (struct mlx5_mp_param *)mp_req.param;
36 : : struct mlx5_mp_arg_mr_manage *arg = &req->args.mr_manage;
37 : : struct mlx5_mp_param *res;
38 : 0 : struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
39 : : int ret;
40 : :
41 : : MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
42 : 0 : mp_init_port_agnostic_msg(&mp_req, MLX5_MP_REQ_CREATE_MR);
43 : 0 : arg->addr = addr;
44 : 0 : arg->cdev = cdev;
45 : 0 : ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
46 [ # # ]: 0 : if (ret) {
47 : 0 : DRV_LOG(ERR, "Create MR request to primary process failed.");
48 : 0 : return -rte_errno;
49 : : }
50 : : MLX5_ASSERT(mp_rep.nb_received == 1);
51 : 0 : mp_res = &mp_rep.msgs[0];
52 : : res = (struct mlx5_mp_param *)mp_res->param;
53 : 0 : ret = res->result;
54 [ # # ]: 0 : if (ret)
55 : 0 : rte_errno = -ret;
56 : 0 : mlx5_free(mp_rep.msgs);
57 : 0 : return ret;
58 : : }
59 : :
60 : : /**
61 : : * @param cdev
62 : : * Pointer to the mlx5 common device.
63 : : * @param mempool
64 : : * Mempool to register or unregister.
65 : : * @param reg
66 : : * True to register the mempool, False to unregister.
67 : : */
68 : : RTE_EXPORT_INTERNAL_SYMBOL(mlx5_mp_req_mempool_reg)
69 : : int
70 : 0 : mlx5_mp_req_mempool_reg(struct mlx5_common_device *cdev,
71 : : struct rte_mempool *mempool, bool reg,
72 : : bool is_extmem)
73 : : {
74 : : struct rte_mp_msg mp_req;
75 : : struct rte_mp_msg *mp_res;
76 : : struct rte_mp_reply mp_rep;
77 : : struct mlx5_mp_param *req = (struct mlx5_mp_param *)mp_req.param;
78 : : struct mlx5_mp_arg_mr_manage *arg = &req->args.mr_manage;
79 : : struct mlx5_mp_param *res;
80 : 0 : struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
81 : : enum mlx5_mp_req_type type;
82 : : int ret;
83 : :
84 : : MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
85 [ # # ]: 0 : type = reg ? MLX5_MP_REQ_MEMPOOL_REGISTER :
86 : : MLX5_MP_REQ_MEMPOOL_UNREGISTER;
87 : 0 : mp_init_port_agnostic_msg(&mp_req, type);
88 : 0 : arg->mempool = mempool;
89 : 0 : arg->is_extmem = is_extmem;
90 : 0 : arg->cdev = cdev;
91 : 0 : ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
92 [ # # ]: 0 : if (ret) {
93 [ # # ]: 0 : DRV_LOG(ERR,
94 : : "Mempool %sregister request to primary process failed.",
95 : : reg ? "" : "un");
96 : 0 : return -rte_errno;
97 : : }
98 : : MLX5_ASSERT(mp_rep.nb_received == 1);
99 : 0 : mp_res = &mp_rep.msgs[0];
100 : : res = (struct mlx5_mp_param *)mp_res->param;
101 : 0 : ret = res->result;
102 [ # # ]: 0 : if (ret)
103 : 0 : rte_errno = -ret;
104 : 0 : mlx5_free(mp_rep.msgs);
105 : 0 : return ret;
106 : : }
107 : :
108 : : /**
109 : : * Request Verbs queue state modification to the primary process.
110 : : *
111 : : * @param[in] mp_id
112 : : * ID of the MP process.
113 : : * @param sm
114 : : * State modify parameters.
115 : : *
116 : : * @return
117 : : * 0 on success, a negative errno value otherwise and rte_errno is set.
118 : : */
119 : : RTE_EXPORT_INTERNAL_SYMBOL(mlx5_mp_req_queue_state_modify)
120 : : int
121 : 0 : mlx5_mp_req_queue_state_modify(struct mlx5_mp_id *mp_id,
122 : : struct mlx5_mp_arg_queue_state_modify *sm)
123 : : {
124 : : struct rte_mp_msg mp_req;
125 : : struct rte_mp_msg *mp_res;
126 : : struct rte_mp_reply mp_rep;
127 : : struct mlx5_mp_param *req = (struct mlx5_mp_param *)mp_req.param;
128 : : struct mlx5_mp_param *res;
129 : 0 : struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
130 : : int ret;
131 : :
132 : : MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
133 : 0 : mp_init_msg(mp_id, &mp_req, MLX5_MP_REQ_QUEUE_STATE_MODIFY);
134 : 0 : req->args.state_modify = *sm;
135 : 0 : ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
136 [ # # ]: 0 : if (ret) {
137 : 0 : DRV_LOG(ERR, "port %u request to primary process failed",
138 : : mp_id->port_id);
139 : 0 : return -rte_errno;
140 : : }
141 : : MLX5_ASSERT(mp_rep.nb_received == 1);
142 : 0 : mp_res = &mp_rep.msgs[0];
143 : : res = (struct mlx5_mp_param *)mp_res->param;
144 : 0 : ret = res->result;
145 : 0 : mlx5_free(mp_rep.msgs);
146 : 0 : return ret;
147 : : }
148 : :
149 : : /**
150 : : * Request Verbs command file descriptor for mmap to the primary process.
151 : : *
152 : : * @param[in] mp_id
153 : : * ID of the MP process.
154 : : *
155 : : * @return
156 : : * fd on success, a negative errno value otherwise and rte_errno is set.
157 : : */
158 : : RTE_EXPORT_INTERNAL_SYMBOL(mlx5_mp_req_verbs_cmd_fd)
159 : : int
160 : 0 : mlx5_mp_req_verbs_cmd_fd(struct mlx5_mp_id *mp_id)
161 : : {
162 : : struct rte_mp_msg mp_req;
163 : : struct rte_mp_msg *mp_res;
164 : : struct rte_mp_reply mp_rep;
165 : : struct mlx5_mp_param *res;
166 : 0 : struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
167 : : int ret;
168 : :
169 : : MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
170 : 0 : mp_init_msg(mp_id, &mp_req, MLX5_MP_REQ_VERBS_CMD_FD);
171 : 0 : ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
172 [ # # ]: 0 : if (ret) {
173 : 0 : DRV_LOG(ERR, "port %u request to primary process failed",
174 : : mp_id->port_id);
175 : 0 : return -rte_errno;
176 : : }
177 : : MLX5_ASSERT(mp_rep.nb_received == 1);
178 : 0 : mp_res = &mp_rep.msgs[0];
179 : : res = (struct mlx5_mp_param *)mp_res->param;
180 [ # # ]: 0 : if (res->result) {
181 : 0 : rte_errno = -res->result;
182 : 0 : DRV_LOG(ERR,
183 : : "port %u failed to get command FD from primary process",
184 : : mp_id->port_id);
185 : 0 : ret = -rte_errno;
186 : 0 : goto exit;
187 : : }
188 : : MLX5_ASSERT(mp_res->num_fds == 1);
189 : 0 : ret = mp_res->fds[0];
190 : 0 : DRV_LOG(DEBUG, "port %u command FD from primary is %d",
191 : : mp_id->port_id, ret);
192 : 0 : exit:
193 : 0 : mlx5_free(mp_rep.msgs);
194 : 0 : return ret;
195 : : }
196 : :
197 : : /**
198 : : * Initialize by primary process.
199 : : */
200 : : RTE_EXPORT_INTERNAL_SYMBOL(mlx5_mp_init_primary)
201 : : int
202 : 0 : mlx5_mp_init_primary(const char *name, const rte_mp_t primary_action)
203 : : {
204 : : int ret;
205 : :
206 : : MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
207 : :
208 : : /* primary is allowed to not support IPC */
209 : 0 : ret = rte_mp_action_register(name, primary_action);
210 [ # # # # ]: 0 : if (ret && rte_errno != ENOTSUP)
211 : 0 : return -1;
212 : : return 0;
213 : : }
214 : :
215 : : /**
216 : : * Un-initialize by primary process.
217 : : */
218 : : RTE_EXPORT_INTERNAL_SYMBOL(mlx5_mp_uninit_primary)
219 : : void
220 : 0 : mlx5_mp_uninit_primary(const char *name)
221 : : {
222 : : MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
223 : 0 : rte_mp_action_unregister(name);
224 : 0 : }
225 : :
226 : : /**
227 : : * Initialize by secondary process.
228 : : */
229 : : RTE_EXPORT_INTERNAL_SYMBOL(mlx5_mp_init_secondary)
230 : : int
231 : 0 : mlx5_mp_init_secondary(const char *name, const rte_mp_t secondary_action)
232 : : {
233 : : MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
234 : 0 : return rte_mp_action_register(name, secondary_action);
235 : : }
236 : :
237 : : /**
238 : : * Un-initialize by secondary process.
239 : : */
240 : : RTE_EXPORT_INTERNAL_SYMBOL(mlx5_mp_uninit_secondary)
241 : : void
242 : 0 : mlx5_mp_uninit_secondary(const char *name)
243 : : {
244 : : MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
245 : 0 : rte_mp_action_unregister(name);
246 : 0 : }
|