common/mlx5: convert control path memory to unified malloc
[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_utils.h"
14 #include "mlx5_malloc.h"
15
16 /**
17  * Request Memory Region creation to the primary process.
18  *
19  * @param[in] mp_id
20  *   ID of the MP process.
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_mp_id *mp_id, 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_param *res;
35         struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
36         int ret;
37
38         MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
39         mp_init_msg(mp_id, &mp_req, MLX5_MP_REQ_CREATE_MR);
40         req->args.addr = addr;
41         ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
42         if (ret) {
43                 DRV_LOG(ERR, "port %u request to primary process failed",
44                         mp_id->port_id);
45                 return -rte_errno;
46         }
47         MLX5_ASSERT(mp_rep.nb_received == 1);
48         mp_res = &mp_rep.msgs[0];
49         res = (struct mlx5_mp_param *)mp_res->param;
50         ret = res->result;
51         if (ret)
52                 rte_errno = -ret;
53         mlx5_free(mp_rep.msgs);
54         return ret;
55 }
56
57 /**
58  * Request Verbs queue state modification to the primary process.
59  *
60  * @param[in] mp_id
61  *   ID of the MP process.
62  * @param sm
63  *   State modify parameters.
64  *
65  * @return
66  *   0 on success, a negative errno value otherwise and rte_errno is set.
67  */
68 int
69 mlx5_mp_req_queue_state_modify(struct mlx5_mp_id *mp_id,
70                                struct mlx5_mp_arg_queue_state_modify *sm)
71 {
72         struct rte_mp_msg mp_req;
73         struct rte_mp_msg *mp_res;
74         struct rte_mp_reply mp_rep;
75         struct mlx5_mp_param *req = (struct mlx5_mp_param *)mp_req.param;
76         struct mlx5_mp_param *res;
77         struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
78         int ret;
79
80         MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
81         mp_init_msg(mp_id, &mp_req, MLX5_MP_REQ_QUEUE_STATE_MODIFY);
82         req->args.state_modify = *sm;
83         ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
84         if (ret) {
85                 DRV_LOG(ERR, "port %u request to primary process failed",
86                         mp_id->port_id);
87                 return -rte_errno;
88         }
89         MLX5_ASSERT(mp_rep.nb_received == 1);
90         mp_res = &mp_rep.msgs[0];
91         res = (struct mlx5_mp_param *)mp_res->param;
92         ret = res->result;
93         mlx5_free(mp_rep.msgs);
94         return ret;
95 }
96
97 /**
98  * Request Verbs command file descriptor for mmap to the primary process.
99  *
100  * @param[in] mp_id
101  *   ID of the MP process.
102  *
103  * @return
104  *   fd on success, a negative errno value otherwise and rte_errno is set.
105  */
106 int
107 mlx5_mp_req_verbs_cmd_fd(struct mlx5_mp_id *mp_id)
108 {
109         struct rte_mp_msg mp_req;
110         struct rte_mp_msg *mp_res;
111         struct rte_mp_reply mp_rep;
112         struct mlx5_mp_param *res;
113         struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
114         int ret;
115
116         MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
117         mp_init_msg(mp_id, &mp_req, MLX5_MP_REQ_VERBS_CMD_FD);
118         ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
119         if (ret) {
120                 DRV_LOG(ERR, "port %u request to primary process failed",
121                         mp_id->port_id);
122                 return -rte_errno;
123         }
124         MLX5_ASSERT(mp_rep.nb_received == 1);
125         mp_res = &mp_rep.msgs[0];
126         res = (struct mlx5_mp_param *)mp_res->param;
127         if (res->result) {
128                 rte_errno = -res->result;
129                 DRV_LOG(ERR,
130                         "port %u failed to get command FD from primary process",
131                         mp_id->port_id);
132                 ret = -rte_errno;
133                 goto exit;
134         }
135         MLX5_ASSERT(mp_res->num_fds == 1);
136         ret = mp_res->fds[0];
137         DRV_LOG(DEBUG, "port %u command FD from primary is %d",
138                 mp_id->port_id, ret);
139 exit:
140         mlx5_free(mp_rep.msgs);
141         return ret;
142 }
143
144 /**
145  * Initialize by primary process.
146  */
147 int
148 mlx5_mp_init_primary(const char *name, const rte_mp_t primary_action)
149 {
150         int ret;
151
152         MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
153
154         /* primary is allowed to not support IPC */
155         ret = rte_mp_action_register(name, primary_action);
156         if (ret && rte_errno != ENOTSUP)
157                 return -1;
158         return 0;
159 }
160
161 /**
162  * Un-initialize by primary process.
163  */
164 void
165 mlx5_mp_uninit_primary(const char *name)
166 {
167         MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
168         rte_mp_action_unregister(name);
169 }
170
171 /**
172  * Initialize by secondary process.
173  */
174 int
175 mlx5_mp_init_secondary(const char *name, const rte_mp_t secondary_action)
176 {
177         MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
178         return rte_mp_action_register(name, secondary_action);
179 }
180
181 /**
182  * Un-initialize by secondary process.
183  */
184 void
185 mlx5_mp_uninit_secondary(const char *name)
186 {
187         MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
188         rte_mp_action_unregister(name);
189 }