xref: /dpdk/lib/eal/common/eal_common_interrupts.c (revision bbbac4cd)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4 
5 #include <stdlib.h>
6 #include <string.h>
7 
8 #include <rte_errno.h>
9 #include <rte_interrupts.h>
10 #include <rte_log.h>
11 #include <rte_malloc.h>
12 
13 /* Macros to check for valid interrupt handle */
14 #define CHECK_VALID_INTR_HANDLE(intr_handle) do { \
15 	if (intr_handle == NULL) { \
16 		RTE_LOG(DEBUG, EAL, "Interrupt instance unallocated\n"); \
17 		rte_errno = EINVAL; \
18 		goto fail; \
19 	} \
20 } while (0)
21 
22 #define RTE_INTR_INSTANCE_KNOWN_FLAGS (RTE_INTR_INSTANCE_F_PRIVATE \
23 	| RTE_INTR_INSTANCE_F_SHARED \
24 	)
25 
26 #define RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags) \
27 	(!!(flags & RTE_INTR_INSTANCE_F_SHARED))
28 
29 struct rte_intr_handle *rte_intr_instance_alloc(uint32_t flags)
30 {
31 	struct rte_intr_handle *intr_handle;
32 	bool uses_rte_memory;
33 
34 	/* Check the flag passed by user, it should be part of the
35 	 * defined flags.
36 	 */
37 	if ((flags & ~RTE_INTR_INSTANCE_KNOWN_FLAGS) != 0) {
38 		RTE_LOG(DEBUG, EAL, "Invalid alloc flag passed 0x%x\n", flags);
39 		rte_errno = EINVAL;
40 		return NULL;
41 	}
42 
43 	uses_rte_memory = RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags);
44 	if (uses_rte_memory)
45 		intr_handle = rte_zmalloc(NULL, sizeof(*intr_handle), 0);
46 	else
47 		intr_handle = calloc(1, sizeof(*intr_handle));
48 	if (intr_handle == NULL) {
49 		RTE_LOG(ERR, EAL, "Failed to allocate intr_handle\n");
50 		rte_errno = ENOMEM;
51 		return NULL;
52 	}
53 
54 	intr_handle->alloc_flags = flags;
55 	intr_handle->nb_intr = RTE_MAX_RXTX_INTR_VEC_ID;
56 
57 	return intr_handle;
58 }
59 
60 struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src)
61 {
62 	struct rte_intr_handle *intr_handle;
63 
64 	if (src == NULL) {
65 		RTE_LOG(DEBUG, EAL, "Source interrupt instance unallocated\n");
66 		rte_errno = EINVAL;
67 		return NULL;
68 	}
69 
70 	intr_handle = rte_intr_instance_alloc(src->alloc_flags);
71 	if (intr_handle != NULL) {
72 		intr_handle->fd = src->fd;
73 		intr_handle->vfio_dev_fd = src->vfio_dev_fd;
74 		intr_handle->type = src->type;
75 		intr_handle->max_intr = src->max_intr;
76 		intr_handle->nb_efd = src->nb_efd;
77 		intr_handle->efd_counter_size = src->efd_counter_size;
78 		memcpy(intr_handle->efds, src->efds, src->nb_intr);
79 		memcpy(intr_handle->elist, src->elist, src->nb_intr);
80 	}
81 
82 	return intr_handle;
83 }
84 
85 void rte_intr_instance_free(struct rte_intr_handle *intr_handle)
86 {
87 	if (intr_handle == NULL)
88 		return;
89 	if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
90 		rte_free(intr_handle);
91 	else
92 		free(intr_handle);
93 }
94 
95 int rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd)
96 {
97 	CHECK_VALID_INTR_HANDLE(intr_handle);
98 
99 	intr_handle->fd = fd;
100 
101 	return 0;
102 fail:
103 	return -rte_errno;
104 }
105 
106 int rte_intr_fd_get(const struct rte_intr_handle *intr_handle)
107 {
108 	CHECK_VALID_INTR_HANDLE(intr_handle);
109 
110 	return intr_handle->fd;
111 fail:
112 	return -1;
113 }
114 
115 int rte_intr_type_set(struct rte_intr_handle *intr_handle,
116 	enum rte_intr_handle_type type)
117 {
118 	CHECK_VALID_INTR_HANDLE(intr_handle);
119 
120 	intr_handle->type = type;
121 
122 	return 0;
123 fail:
124 	return -rte_errno;
125 }
126 
127 enum rte_intr_handle_type rte_intr_type_get(
128 	const struct rte_intr_handle *intr_handle)
129 {
130 	CHECK_VALID_INTR_HANDLE(intr_handle);
131 
132 	return intr_handle->type;
133 fail:
134 	return RTE_INTR_HANDLE_UNKNOWN;
135 }
136 
137 int rte_intr_dev_fd_set(struct rte_intr_handle *intr_handle, int fd)
138 {
139 	CHECK_VALID_INTR_HANDLE(intr_handle);
140 
141 	intr_handle->vfio_dev_fd = fd;
142 
143 	return 0;
144 fail:
145 	return -rte_errno;
146 }
147 
148 int rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle)
149 {
150 	CHECK_VALID_INTR_HANDLE(intr_handle);
151 
152 	return intr_handle->vfio_dev_fd;
153 fail:
154 	return -1;
155 }
156 
157 int rte_intr_max_intr_set(struct rte_intr_handle *intr_handle,
158 				 int max_intr)
159 {
160 	CHECK_VALID_INTR_HANDLE(intr_handle);
161 
162 	if (max_intr > intr_handle->nb_intr) {
163 		RTE_LOG(DEBUG, EAL, "Maximum interrupt vector ID (%d) exceeds "
164 			"the number of available events (%d)\n", max_intr,
165 			intr_handle->nb_intr);
166 		rte_errno = ERANGE;
167 		goto fail;
168 	}
169 
170 	intr_handle->max_intr = max_intr;
171 
172 	return 0;
173 fail:
174 	return -rte_errno;
175 }
176 
177 int rte_intr_max_intr_get(const struct rte_intr_handle *intr_handle)
178 {
179 	CHECK_VALID_INTR_HANDLE(intr_handle);
180 
181 	return intr_handle->max_intr;
182 fail:
183 	return -rte_errno;
184 }
185 
186 int rte_intr_nb_efd_set(struct rte_intr_handle *intr_handle, int nb_efd)
187 {
188 	CHECK_VALID_INTR_HANDLE(intr_handle);
189 
190 	intr_handle->nb_efd = nb_efd;
191 
192 	return 0;
193 fail:
194 	return -rte_errno;
195 }
196 
197 int rte_intr_nb_efd_get(const struct rte_intr_handle *intr_handle)
198 {
199 	CHECK_VALID_INTR_HANDLE(intr_handle);
200 
201 	return intr_handle->nb_efd;
202 fail:
203 	return -rte_errno;
204 }
205 
206 int rte_intr_nb_intr_get(const struct rte_intr_handle *intr_handle)
207 {
208 	CHECK_VALID_INTR_HANDLE(intr_handle);
209 
210 	return intr_handle->nb_intr;
211 fail:
212 	return -rte_errno;
213 }
214 
215 int rte_intr_efd_counter_size_set(struct rte_intr_handle *intr_handle,
216 	uint8_t efd_counter_size)
217 {
218 	CHECK_VALID_INTR_HANDLE(intr_handle);
219 
220 	intr_handle->efd_counter_size = efd_counter_size;
221 
222 	return 0;
223 fail:
224 	return -rte_errno;
225 }
226 
227 int rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle)
228 {
229 	CHECK_VALID_INTR_HANDLE(intr_handle);
230 
231 	return intr_handle->efd_counter_size;
232 fail:
233 	return -rte_errno;
234 }
235 
236 int rte_intr_efds_index_get(const struct rte_intr_handle *intr_handle,
237 	int index)
238 {
239 	CHECK_VALID_INTR_HANDLE(intr_handle);
240 
241 	if (index >= intr_handle->nb_intr) {
242 		RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
243 			intr_handle->nb_intr);
244 		rte_errno = EINVAL;
245 		goto fail;
246 	}
247 
248 	return intr_handle->efds[index];
249 fail:
250 	return -rte_errno;
251 }
252 
253 int rte_intr_efds_index_set(struct rte_intr_handle *intr_handle,
254 	int index, int fd)
255 {
256 	CHECK_VALID_INTR_HANDLE(intr_handle);
257 
258 	if (index >= intr_handle->nb_intr) {
259 		RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
260 			intr_handle->nb_intr);
261 		rte_errno = ERANGE;
262 		goto fail;
263 	}
264 
265 	intr_handle->efds[index] = fd;
266 
267 	return 0;
268 fail:
269 	return -rte_errno;
270 }
271 
272 struct rte_epoll_event *rte_intr_elist_index_get(
273 	struct rte_intr_handle *intr_handle, int index)
274 {
275 	CHECK_VALID_INTR_HANDLE(intr_handle);
276 
277 	if (index >= intr_handle->nb_intr) {
278 		RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
279 			intr_handle->nb_intr);
280 		rte_errno = ERANGE;
281 		goto fail;
282 	}
283 
284 	return &intr_handle->elist[index];
285 fail:
286 	return NULL;
287 }
288 
289 int rte_intr_elist_index_set(struct rte_intr_handle *intr_handle,
290 	int index, struct rte_epoll_event elist)
291 {
292 	CHECK_VALID_INTR_HANDLE(intr_handle);
293 
294 	if (index >= intr_handle->nb_intr) {
295 		RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
296 			intr_handle->nb_intr);
297 		rte_errno = ERANGE;
298 		goto fail;
299 	}
300 
301 	intr_handle->elist[index] = elist;
302 
303 	return 0;
304 fail:
305 	return -rte_errno;
306 }
307 
308 int rte_intr_vec_list_alloc(struct rte_intr_handle *intr_handle,
309 	const char *name, int size)
310 {
311 	CHECK_VALID_INTR_HANDLE(intr_handle);
312 
313 	/* Vector list already allocated */
314 	if (intr_handle->intr_vec != NULL)
315 		return 0;
316 
317 	if (size > intr_handle->nb_intr) {
318 		RTE_LOG(DEBUG, EAL, "Invalid size %d, max limit %d\n", size,
319 			intr_handle->nb_intr);
320 		rte_errno = ERANGE;
321 		goto fail;
322 	}
323 
324 	if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
325 		intr_handle->intr_vec = rte_zmalloc(name, size * sizeof(int), 0);
326 	else
327 		intr_handle->intr_vec = calloc(size, sizeof(int));
328 	if (intr_handle->intr_vec == NULL) {
329 		RTE_LOG(ERR, EAL, "Failed to allocate %d intr_vec\n", size);
330 		rte_errno = ENOMEM;
331 		goto fail;
332 	}
333 
334 	intr_handle->vec_list_size = size;
335 
336 	return 0;
337 fail:
338 	return -rte_errno;
339 }
340 
341 int rte_intr_vec_list_index_get(const struct rte_intr_handle *intr_handle,
342 				int index)
343 {
344 	CHECK_VALID_INTR_HANDLE(intr_handle);
345 
346 	if (index >= intr_handle->vec_list_size) {
347 		RTE_LOG(DEBUG, EAL, "Index %d greater than vec list size %d\n",
348 			index, intr_handle->vec_list_size);
349 		rte_errno = ERANGE;
350 		goto fail;
351 	}
352 
353 	return intr_handle->intr_vec[index];
354 fail:
355 	return -rte_errno;
356 }
357 
358 int rte_intr_vec_list_index_set(struct rte_intr_handle *intr_handle,
359 				int index, int vec)
360 {
361 	CHECK_VALID_INTR_HANDLE(intr_handle);
362 
363 	if (index >= intr_handle->vec_list_size) {
364 		RTE_LOG(DEBUG, EAL, "Index %d greater than vec list size %d\n",
365 			index, intr_handle->vec_list_size);
366 		rte_errno = ERANGE;
367 		goto fail;
368 	}
369 
370 	intr_handle->intr_vec[index] = vec;
371 
372 	return 0;
373 fail:
374 	return -rte_errno;
375 }
376 
377 void rte_intr_vec_list_free(struct rte_intr_handle *intr_handle)
378 {
379 	if (intr_handle == NULL)
380 		return;
381 	if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
382 		rte_free(intr_handle->intr_vec);
383 	else
384 		free(intr_handle->intr_vec);
385 	intr_handle->intr_vec = NULL;
386 	intr_handle->vec_list_size = 0;
387 }
388 
389 void *rte_intr_instance_windows_handle_get(struct rte_intr_handle *intr_handle)
390 {
391 	CHECK_VALID_INTR_HANDLE(intr_handle);
392 
393 	return intr_handle->windows_handle;
394 fail:
395 	return NULL;
396 }
397 
398 int rte_intr_instance_windows_handle_set(struct rte_intr_handle *intr_handle,
399 	void *windows_handle)
400 {
401 	CHECK_VALID_INTR_HANDLE(intr_handle);
402 
403 	intr_handle->windows_handle = windows_handle;
404 
405 	return 0;
406 fail:
407 	return -rte_errno;
408 }
409