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