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