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