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