1a4de9586SVu Pham /* SPDX-License-Identifier: BSD-3-Clause
2a4de9586SVu Pham * Copyright 2019 6WIND S.A.
3a4de9586SVu Pham * Copyright 2019 Mellanox Technologies, Ltd
4a4de9586SVu Pham */
5a4de9586SVu Pham
6a4de9586SVu Pham #include <stdio.h>
7a4de9586SVu Pham #include <time.h>
8a4de9586SVu Pham
9a4de9586SVu Pham #include <rte_eal.h>
10a4de9586SVu Pham #include <rte_errno.h>
11a4de9586SVu Pham
12a4de9586SVu Pham #include "mlx5_common_mp.h"
1325245d5dSShiri Kuzin #include "mlx5_common_log.h"
1466914d19SSuanming Mou #include "mlx5_malloc.h"
15a4de9586SVu Pham
16a4de9586SVu Pham /**
17a4de9586SVu Pham * Request Memory Region creation to the primary process.
18a4de9586SVu Pham *
1920489176SMichael Baum * @param cdev
2020489176SMichael Baum * Pointer to the mlx5 common device.
21a4de9586SVu Pham * @param addr
22a4de9586SVu Pham * Target virtual address to register.
23a4de9586SVu Pham *
24a4de9586SVu Pham * @return
25a4de9586SVu Pham * 0 on success, a negative errno value otherwise and rte_errno is set.
26a4de9586SVu Pham */
27a4de9586SVu Pham int
mlx5_mp_req_mr_create(struct mlx5_common_device * cdev,uintptr_t addr)2820489176SMichael Baum mlx5_mp_req_mr_create(struct mlx5_common_device *cdev, uintptr_t addr)
29a4de9586SVu Pham {
30a4de9586SVu Pham struct rte_mp_msg mp_req;
31a4de9586SVu Pham struct rte_mp_msg *mp_res;
32a4de9586SVu Pham struct rte_mp_reply mp_rep;
33a4de9586SVu Pham struct mlx5_mp_param *req = (struct mlx5_mp_param *)mp_req.param;
3420489176SMichael Baum struct mlx5_mp_arg_mr_manage *arg = &req->args.mr_manage;
35a4de9586SVu Pham struct mlx5_mp_param *res;
36a4de9586SVu Pham struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
37a4de9586SVu Pham int ret;
38a4de9586SVu Pham
39a4de9586SVu Pham MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
4020489176SMichael Baum mp_init_port_agnostic_msg(&mp_req, MLX5_MP_REQ_CREATE_MR);
4120489176SMichael Baum arg->addr = addr;
4220489176SMichael Baum arg->cdev = cdev;
43a4de9586SVu Pham ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
44a4de9586SVu Pham if (ret) {
4520489176SMichael Baum DRV_LOG(ERR, "Create MR request to primary process failed.");
46a4de9586SVu Pham return -rte_errno;
47a4de9586SVu Pham }
48a4de9586SVu Pham MLX5_ASSERT(mp_rep.nb_received == 1);
49a4de9586SVu Pham mp_res = &mp_rep.msgs[0];
50a4de9586SVu Pham res = (struct mlx5_mp_param *)mp_res->param;
51a4de9586SVu Pham ret = res->result;
52a4de9586SVu Pham if (ret)
53a4de9586SVu Pham rte_errno = -ret;
5466914d19SSuanming Mou mlx5_free(mp_rep.msgs);
55a4de9586SVu Pham return ret;
56a4de9586SVu Pham }
57a4de9586SVu Pham
58a4de9586SVu Pham /**
5920489176SMichael Baum * @param cdev
6020489176SMichael Baum * Pointer to the mlx5 common device.
61690b2a88SDmitry Kozlyuk * @param mempool
62690b2a88SDmitry Kozlyuk * Mempool to register or unregister.
63690b2a88SDmitry Kozlyuk * @param reg
64690b2a88SDmitry Kozlyuk * True to register the mempool, False to unregister.
65690b2a88SDmitry Kozlyuk */
66690b2a88SDmitry Kozlyuk int
mlx5_mp_req_mempool_reg(struct mlx5_common_device * cdev,struct rte_mempool * mempool,bool reg,bool is_extmem)6720489176SMichael Baum mlx5_mp_req_mempool_reg(struct mlx5_common_device *cdev,
68*08ac0358SDmitry Kozlyuk struct rte_mempool *mempool, bool reg,
69*08ac0358SDmitry Kozlyuk bool is_extmem)
70690b2a88SDmitry Kozlyuk {
71690b2a88SDmitry Kozlyuk struct rte_mp_msg mp_req;
72690b2a88SDmitry Kozlyuk struct rte_mp_msg *mp_res;
73690b2a88SDmitry Kozlyuk struct rte_mp_reply mp_rep;
74690b2a88SDmitry Kozlyuk struct mlx5_mp_param *req = (struct mlx5_mp_param *)mp_req.param;
7520489176SMichael Baum struct mlx5_mp_arg_mr_manage *arg = &req->args.mr_manage;
76690b2a88SDmitry Kozlyuk struct mlx5_mp_param *res;
77690b2a88SDmitry Kozlyuk struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
78690b2a88SDmitry Kozlyuk enum mlx5_mp_req_type type;
79690b2a88SDmitry Kozlyuk int ret;
80690b2a88SDmitry Kozlyuk
81690b2a88SDmitry Kozlyuk MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
82690b2a88SDmitry Kozlyuk type = reg ? MLX5_MP_REQ_MEMPOOL_REGISTER :
83690b2a88SDmitry Kozlyuk MLX5_MP_REQ_MEMPOOL_UNREGISTER;
8420489176SMichael Baum mp_init_port_agnostic_msg(&mp_req, type);
85690b2a88SDmitry Kozlyuk arg->mempool = mempool;
86*08ac0358SDmitry Kozlyuk arg->is_extmem = is_extmem;
8720489176SMichael Baum arg->cdev = cdev;
88690b2a88SDmitry Kozlyuk ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
89690b2a88SDmitry Kozlyuk if (ret) {
9020489176SMichael Baum DRV_LOG(ERR,
9120489176SMichael Baum "Mempool %sregister request to primary process failed.",
9220489176SMichael Baum reg ? "" : "un");
93690b2a88SDmitry Kozlyuk return -rte_errno;
94690b2a88SDmitry Kozlyuk }
95690b2a88SDmitry Kozlyuk MLX5_ASSERT(mp_rep.nb_received == 1);
96690b2a88SDmitry Kozlyuk mp_res = &mp_rep.msgs[0];
97690b2a88SDmitry Kozlyuk res = (struct mlx5_mp_param *)mp_res->param;
98690b2a88SDmitry Kozlyuk ret = res->result;
99690b2a88SDmitry Kozlyuk if (ret)
100690b2a88SDmitry Kozlyuk rte_errno = -ret;
101690b2a88SDmitry Kozlyuk mlx5_free(mp_rep.msgs);
102690b2a88SDmitry Kozlyuk return ret;
103690b2a88SDmitry Kozlyuk }
104690b2a88SDmitry Kozlyuk
105690b2a88SDmitry Kozlyuk /**
106a4de9586SVu Pham * Request Verbs queue state modification to the primary process.
107a4de9586SVu Pham *
108a4de9586SVu Pham * @param[in] mp_id
109a4de9586SVu Pham * ID of the MP process.
110a4de9586SVu Pham * @param sm
111a4de9586SVu Pham * State modify parameters.
112a4de9586SVu Pham *
113a4de9586SVu Pham * @return
114a4de9586SVu Pham * 0 on success, a negative errno value otherwise and rte_errno is set.
115a4de9586SVu Pham */
116a4de9586SVu Pham int
mlx5_mp_req_queue_state_modify(struct mlx5_mp_id * mp_id,struct mlx5_mp_arg_queue_state_modify * sm)117a4de9586SVu Pham mlx5_mp_req_queue_state_modify(struct mlx5_mp_id *mp_id,
118a4de9586SVu Pham struct mlx5_mp_arg_queue_state_modify *sm)
119a4de9586SVu Pham {
120a4de9586SVu Pham struct rte_mp_msg mp_req;
121a4de9586SVu Pham struct rte_mp_msg *mp_res;
122a4de9586SVu Pham struct rte_mp_reply mp_rep;
123a4de9586SVu Pham struct mlx5_mp_param *req = (struct mlx5_mp_param *)mp_req.param;
124a4de9586SVu Pham struct mlx5_mp_param *res;
125a4de9586SVu Pham struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
126a4de9586SVu Pham int ret;
127a4de9586SVu Pham
128a4de9586SVu Pham MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
129a4de9586SVu Pham mp_init_msg(mp_id, &mp_req, MLX5_MP_REQ_QUEUE_STATE_MODIFY);
130a4de9586SVu Pham req->args.state_modify = *sm;
131a4de9586SVu Pham ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
132a4de9586SVu Pham if (ret) {
133a4de9586SVu Pham DRV_LOG(ERR, "port %u request to primary process failed",
134a4de9586SVu Pham mp_id->port_id);
135a4de9586SVu Pham return -rte_errno;
136a4de9586SVu Pham }
137a4de9586SVu Pham MLX5_ASSERT(mp_rep.nb_received == 1);
138a4de9586SVu Pham mp_res = &mp_rep.msgs[0];
139a4de9586SVu Pham res = (struct mlx5_mp_param *)mp_res->param;
140a4de9586SVu Pham ret = res->result;
14166914d19SSuanming Mou mlx5_free(mp_rep.msgs);
142a4de9586SVu Pham return ret;
143a4de9586SVu Pham }
144a4de9586SVu Pham
145a4de9586SVu Pham /**
146a4de9586SVu Pham * Request Verbs command file descriptor for mmap to the primary process.
147a4de9586SVu Pham *
148a4de9586SVu Pham * @param[in] mp_id
149a4de9586SVu Pham * ID of the MP process.
150a4de9586SVu Pham *
151a4de9586SVu Pham * @return
152a4de9586SVu Pham * fd on success, a negative errno value otherwise and rte_errno is set.
153a4de9586SVu Pham */
154a4de9586SVu Pham int
mlx5_mp_req_verbs_cmd_fd(struct mlx5_mp_id * mp_id)155a4de9586SVu Pham mlx5_mp_req_verbs_cmd_fd(struct mlx5_mp_id *mp_id)
156a4de9586SVu Pham {
157a4de9586SVu Pham struct rte_mp_msg mp_req;
158a4de9586SVu Pham struct rte_mp_msg *mp_res;
159a4de9586SVu Pham struct rte_mp_reply mp_rep;
160a4de9586SVu Pham struct mlx5_mp_param *res;
161a4de9586SVu Pham struct timespec ts = {.tv_sec = MLX5_MP_REQ_TIMEOUT_SEC, .tv_nsec = 0};
162a4de9586SVu Pham int ret;
163a4de9586SVu Pham
164a4de9586SVu Pham MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
165a4de9586SVu Pham mp_init_msg(mp_id, &mp_req, MLX5_MP_REQ_VERBS_CMD_FD);
166a4de9586SVu Pham ret = rte_mp_request_sync(&mp_req, &mp_rep, &ts);
167a4de9586SVu Pham if (ret) {
168a4de9586SVu Pham DRV_LOG(ERR, "port %u request to primary process failed",
169a4de9586SVu Pham mp_id->port_id);
170a4de9586SVu Pham return -rte_errno;
171a4de9586SVu Pham }
172a4de9586SVu Pham MLX5_ASSERT(mp_rep.nb_received == 1);
173a4de9586SVu Pham mp_res = &mp_rep.msgs[0];
174a4de9586SVu Pham res = (struct mlx5_mp_param *)mp_res->param;
175a4de9586SVu Pham if (res->result) {
176a4de9586SVu Pham rte_errno = -res->result;
177a4de9586SVu Pham DRV_LOG(ERR,
178a4de9586SVu Pham "port %u failed to get command FD from primary process",
179a4de9586SVu Pham mp_id->port_id);
180a4de9586SVu Pham ret = -rte_errno;
181a4de9586SVu Pham goto exit;
182a4de9586SVu Pham }
183a4de9586SVu Pham MLX5_ASSERT(mp_res->num_fds == 1);
184a4de9586SVu Pham ret = mp_res->fds[0];
185a4de9586SVu Pham DRV_LOG(DEBUG, "port %u command FD from primary is %d",
186a4de9586SVu Pham mp_id->port_id, ret);
187a4de9586SVu Pham exit:
18866914d19SSuanming Mou mlx5_free(mp_rep.msgs);
189a4de9586SVu Pham return ret;
190a4de9586SVu Pham }
191a4de9586SVu Pham
192a4de9586SVu Pham /**
193a4de9586SVu Pham * Initialize by primary process.
194a4de9586SVu Pham */
195a4de9586SVu Pham int
mlx5_mp_init_primary(const char * name,const rte_mp_t primary_action)196a4de9586SVu Pham mlx5_mp_init_primary(const char *name, const rte_mp_t primary_action)
197a4de9586SVu Pham {
198a4de9586SVu Pham int ret;
199a4de9586SVu Pham
200a4de9586SVu Pham MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
201a4de9586SVu Pham
202a4de9586SVu Pham /* primary is allowed to not support IPC */
203a4de9586SVu Pham ret = rte_mp_action_register(name, primary_action);
204a4de9586SVu Pham if (ret && rte_errno != ENOTSUP)
205a4de9586SVu Pham return -1;
206a4de9586SVu Pham return 0;
207a4de9586SVu Pham }
208a4de9586SVu Pham
209a4de9586SVu Pham /**
210a4de9586SVu Pham * Un-initialize by primary process.
211a4de9586SVu Pham */
212a4de9586SVu Pham void
mlx5_mp_uninit_primary(const char * name)213a4de9586SVu Pham mlx5_mp_uninit_primary(const char *name)
214a4de9586SVu Pham {
215a4de9586SVu Pham MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
216a4de9586SVu Pham rte_mp_action_unregister(name);
217a4de9586SVu Pham }
218a4de9586SVu Pham
219a4de9586SVu Pham /**
220a4de9586SVu Pham * Initialize by secondary process.
221a4de9586SVu Pham */
222a4de9586SVu Pham int
mlx5_mp_init_secondary(const char * name,const rte_mp_t secondary_action)223a4de9586SVu Pham mlx5_mp_init_secondary(const char *name, const rte_mp_t secondary_action)
224a4de9586SVu Pham {
225a4de9586SVu Pham MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
226a4de9586SVu Pham return rte_mp_action_register(name, secondary_action);
227a4de9586SVu Pham }
228a4de9586SVu Pham
229a4de9586SVu Pham /**
230a4de9586SVu Pham * Un-initialize by secondary process.
231a4de9586SVu Pham */
232a4de9586SVu Pham void
mlx5_mp_uninit_secondary(const char * name)233a4de9586SVu Pham mlx5_mp_uninit_secondary(const char *name)
234a4de9586SVu Pham {
235a4de9586SVu Pham MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_SECONDARY);
236a4de9586SVu Pham rte_mp_action_unregister(name);
237a4de9586SVu Pham }
238