Branch data Line data Source code
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 : : #include "eal_interrupts.h"
14 : : #include "eal_private.h"
15 : :
16 : : /* Macros to check for valid interrupt handle */
17 : : #define CHECK_VALID_INTR_HANDLE(intr_handle) do { \
18 : : if (intr_handle == NULL) { \
19 : : EAL_LOG(DEBUG, "Interrupt instance unallocated"); \
20 : : rte_errno = EINVAL; \
21 : : goto fail; \
22 : : } \
23 : : } while (0)
24 : :
25 : : #define RTE_INTR_INSTANCE_KNOWN_FLAGS (RTE_INTR_INSTANCE_F_PRIVATE \
26 : : | RTE_INTR_INSTANCE_F_SHARED \
27 : : )
28 : :
29 : : #define RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags) \
30 : : (!!(flags & RTE_INTR_INSTANCE_F_SHARED))
31 : :
32 : 548 : struct rte_intr_handle *rte_intr_instance_alloc(uint32_t flags)
33 : : {
34 : : struct rte_intr_handle *intr_handle;
35 : : bool uses_rte_memory;
36 : :
37 : : /* Check the flag passed by user, it should be part of the
38 : : * defined flags.
39 : : */
40 [ - + ]: 548 : if ((flags & ~RTE_INTR_INSTANCE_KNOWN_FLAGS) != 0) {
41 : 0 : EAL_LOG(DEBUG, "Invalid alloc flag passed 0x%x", flags);
42 : 0 : rte_errno = EINVAL;
43 : 0 : return NULL;
44 : : }
45 : :
46 : 548 : uses_rte_memory = RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags);
47 [ - + ]: 548 : if (uses_rte_memory)
48 : 0 : intr_handle = rte_zmalloc(NULL, sizeof(*intr_handle), 0);
49 : : else
50 : 548 : intr_handle = calloc(1, sizeof(*intr_handle));
51 [ - + ]: 548 : if (intr_handle == NULL) {
52 : 0 : EAL_LOG(ERR, "Failed to allocate intr_handle");
53 : 0 : rte_errno = ENOMEM;
54 : 0 : return NULL;
55 : : }
56 : :
57 [ - + ]: 548 : if (uses_rte_memory) {
58 : 0 : intr_handle->efds = rte_zmalloc(NULL,
59 : : RTE_MAX_RXTX_INTR_VEC_ID * sizeof(int), 0);
60 : : } else {
61 : 548 : intr_handle->efds = calloc(RTE_MAX_RXTX_INTR_VEC_ID,
62 : : sizeof(int));
63 : : }
64 [ - + ]: 548 : if (intr_handle->efds == NULL) {
65 : 0 : EAL_LOG(ERR, "Fail to allocate event fd list");
66 : 0 : rte_errno = ENOMEM;
67 : 0 : goto fail;
68 : : }
69 : :
70 [ - + ]: 548 : if (uses_rte_memory) {
71 : 0 : intr_handle->elist = rte_zmalloc(NULL,
72 : : RTE_MAX_RXTX_INTR_VEC_ID * sizeof(struct rte_epoll_event),
73 : : 0);
74 : : } else {
75 : 548 : intr_handle->elist = calloc(RTE_MAX_RXTX_INTR_VEC_ID,
76 : : sizeof(struct rte_epoll_event));
77 : : }
78 [ - + ]: 548 : if (intr_handle->elist == NULL) {
79 : 0 : EAL_LOG(ERR, "fail to allocate event fd list");
80 : 0 : rte_errno = ENOMEM;
81 : 0 : goto fail;
82 : : }
83 : :
84 : 548 : intr_handle->alloc_flags = flags;
85 : 548 : intr_handle->nb_intr = RTE_MAX_RXTX_INTR_VEC_ID;
86 : :
87 : 548 : return intr_handle;
88 : 0 : fail:
89 [ # # ]: 0 : if (uses_rte_memory) {
90 : 0 : rte_free(intr_handle->efds);
91 : 0 : rte_free(intr_handle);
92 : : } else {
93 : 0 : free(intr_handle->efds);
94 : 0 : free(intr_handle);
95 : : }
96 : : return NULL;
97 : : }
98 : :
99 : 7 : struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src)
100 : : {
101 : : struct rte_intr_handle *intr_handle;
102 : :
103 [ - + ]: 7 : if (src == NULL) {
104 : 0 : EAL_LOG(DEBUG, "Source interrupt instance unallocated");
105 : 0 : rte_errno = EINVAL;
106 : 0 : return NULL;
107 : : }
108 : :
109 : 7 : intr_handle = rte_intr_instance_alloc(src->alloc_flags);
110 [ + - ]: 7 : if (intr_handle != NULL) {
111 : 7 : intr_handle->fd = src->fd;
112 : 7 : intr_handle->dev_fd = src->dev_fd;
113 : 7 : intr_handle->type = src->type;
114 : 7 : intr_handle->max_intr = src->max_intr;
115 : 7 : intr_handle->nb_efd = src->nb_efd;
116 : 7 : intr_handle->efd_counter_size = src->efd_counter_size;
117 : 7 : memcpy(intr_handle->efds, src->efds, src->nb_intr);
118 : 7 : memcpy(intr_handle->elist, src->elist, src->nb_intr);
119 : : }
120 : :
121 : : return intr_handle;
122 : : }
123 : :
124 : 0 : int rte_intr_event_list_update(struct rte_intr_handle *intr_handle, int size)
125 : : {
126 : : struct rte_epoll_event *tmp_elist;
127 : : bool uses_rte_memory;
128 : : int *tmp_efds;
129 : :
130 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
131 : :
132 [ # # ]: 0 : if (size == 0) {
133 : 0 : EAL_LOG(DEBUG, "Size can't be zero");
134 : 0 : rte_errno = EINVAL;
135 : 0 : goto fail;
136 : : }
137 : :
138 : : uses_rte_memory =
139 : 0 : RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags);
140 [ # # ]: 0 : if (uses_rte_memory) {
141 : 0 : tmp_efds = rte_realloc(intr_handle->efds, size * sizeof(int),
142 : : 0);
143 : : } else {
144 : 0 : tmp_efds = realloc(intr_handle->efds, size * sizeof(int));
145 : : }
146 [ # # ]: 0 : if (tmp_efds == NULL) {
147 : 0 : EAL_LOG(ERR, "Failed to realloc the efds list");
148 : 0 : rte_errno = ENOMEM;
149 : 0 : goto fail;
150 : : }
151 : 0 : intr_handle->efds = tmp_efds;
152 : :
153 [ # # ]: 0 : if (uses_rte_memory) {
154 : 0 : tmp_elist = rte_realloc(intr_handle->elist,
155 : : size * sizeof(struct rte_epoll_event), 0);
156 : : } else {
157 : 0 : tmp_elist = realloc(intr_handle->elist,
158 : : size * sizeof(struct rte_epoll_event));
159 : : }
160 [ # # ]: 0 : if (tmp_elist == NULL) {
161 : 0 : EAL_LOG(ERR, "Failed to realloc the event list");
162 : 0 : rte_errno = ENOMEM;
163 : 0 : goto fail;
164 : : }
165 : 0 : intr_handle->elist = tmp_elist;
166 : :
167 : 0 : intr_handle->nb_intr = size;
168 : :
169 : 0 : return 0;
170 : 0 : fail:
171 : 0 : return -rte_errno;
172 : : }
173 : :
174 : 14655 : void rte_intr_instance_free(struct rte_intr_handle *intr_handle)
175 : : {
176 [ + + ]: 14655 : if (intr_handle == NULL)
177 : : return;
178 [ - + ]: 546 : if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags)) {
179 : 0 : rte_free(intr_handle->efds);
180 : 0 : rte_free(intr_handle->elist);
181 : 0 : rte_free(intr_handle);
182 : : } else {
183 : 546 : free(intr_handle->efds);
184 : 546 : free(intr_handle->elist);
185 : 546 : free(intr_handle);
186 : : }
187 : : }
188 : :
189 : 191 : int rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd)
190 : : {
191 [ - + ]: 191 : CHECK_VALID_INTR_HANDLE(intr_handle);
192 : :
193 : 191 : intr_handle->fd = fd;
194 : :
195 : 191 : return 0;
196 : : fail:
197 : 0 : return -rte_errno;
198 : : }
199 : :
200 : 4916256 : int rte_intr_fd_get(const struct rte_intr_handle *intr_handle)
201 : : {
202 [ + + ]: 4916256 : CHECK_VALID_INTR_HANDLE(intr_handle);
203 : :
204 : 4916254 : return intr_handle->fd;
205 : : fail:
206 : 2 : return -1;
207 : : }
208 : :
209 : 191 : int rte_intr_type_set(struct rte_intr_handle *intr_handle,
210 : : enum rte_intr_handle_type type)
211 : : {
212 [ - + ]: 191 : CHECK_VALID_INTR_HANDLE(intr_handle);
213 : :
214 : 191 : intr_handle->type = type;
215 : :
216 : 191 : return 0;
217 : : fail:
218 : 0 : return -rte_errno;
219 : : }
220 : :
221 : 313136 : enum rte_intr_handle_type rte_intr_type_get(
222 : : const struct rte_intr_handle *intr_handle)
223 : : {
224 [ - + ]: 313136 : CHECK_VALID_INTR_HANDLE(intr_handle);
225 : :
226 : 313136 : return intr_handle->type;
227 : : fail:
228 : 0 : return RTE_INTR_HANDLE_UNKNOWN;
229 : : }
230 : :
231 : 0 : int rte_intr_dev_fd_set(struct rte_intr_handle *intr_handle, int fd)
232 : : {
233 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
234 : :
235 : 0 : intr_handle->dev_fd = fd;
236 : :
237 : 0 : return 0;
238 : : fail:
239 : 0 : return -rte_errno;
240 : : }
241 : :
242 : 12 : int rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle)
243 : : {
244 [ - + ]: 12 : CHECK_VALID_INTR_HANDLE(intr_handle);
245 : :
246 : 12 : return intr_handle->dev_fd;
247 : : fail:
248 : 0 : return -1;
249 : : }
250 : :
251 : 0 : int rte_intr_max_intr_set(struct rte_intr_handle *intr_handle,
252 : : int max_intr)
253 : : {
254 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
255 : :
256 [ # # ]: 0 : if (max_intr > intr_handle->nb_intr) {
257 : 0 : EAL_LOG(DEBUG, "Maximum interrupt vector ID (%d) exceeds "
258 : : "the number of available events (%d)", max_intr,
259 : : intr_handle->nb_intr);
260 : 0 : rte_errno = ERANGE;
261 : 0 : goto fail;
262 : : }
263 : :
264 : 0 : intr_handle->max_intr = max_intr;
265 : :
266 : 0 : return 0;
267 : 0 : fail:
268 : 0 : return -rte_errno;
269 : : }
270 : :
271 : 0 : int rte_intr_max_intr_get(const struct rte_intr_handle *intr_handle)
272 : : {
273 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
274 : :
275 : 0 : return intr_handle->max_intr;
276 : : fail:
277 : 0 : return -rte_errno;
278 : : }
279 : :
280 : 0 : int rte_intr_nb_efd_set(struct rte_intr_handle *intr_handle, int nb_efd)
281 : : {
282 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
283 : :
284 : 0 : intr_handle->nb_efd = nb_efd;
285 : :
286 : 0 : return 0;
287 : : fail:
288 : 0 : return -rte_errno;
289 : : }
290 : :
291 : 0 : int rte_intr_nb_efd_get(const struct rte_intr_handle *intr_handle)
292 : : {
293 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
294 : :
295 : 0 : return intr_handle->nb_efd;
296 : : fail:
297 : 0 : return -rte_errno;
298 : : }
299 : :
300 : 0 : int rte_intr_nb_intr_get(const struct rte_intr_handle *intr_handle)
301 : : {
302 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
303 : :
304 : 0 : return intr_handle->nb_intr;
305 : : fail:
306 : 0 : return -rte_errno;
307 : : }
308 : :
309 : 0 : int rte_intr_efd_counter_size_set(struct rte_intr_handle *intr_handle,
310 : : uint8_t efd_counter_size)
311 : : {
312 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
313 : :
314 : 0 : intr_handle->efd_counter_size = efd_counter_size;
315 : :
316 : 0 : return 0;
317 : : fail:
318 : 0 : return -rte_errno;
319 : : }
320 : :
321 : 0 : int rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle)
322 : : {
323 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
324 : :
325 : 0 : return intr_handle->efd_counter_size;
326 : : fail:
327 : 0 : return -rte_errno;
328 : : }
329 : :
330 : 0 : int rte_intr_efds_index_get(const struct rte_intr_handle *intr_handle,
331 : : int index)
332 : : {
333 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
334 : :
335 [ # # ]: 0 : if (index >= intr_handle->nb_intr) {
336 : 0 : EAL_LOG(DEBUG, "Invalid index %d, max limit %d", index,
337 : : intr_handle->nb_intr);
338 : 0 : rte_errno = EINVAL;
339 : 0 : goto fail;
340 : : }
341 : :
342 : 0 : return intr_handle->efds[index];
343 : 0 : fail:
344 : 0 : return -rte_errno;
345 : : }
346 : :
347 : 0 : int rte_intr_efds_index_set(struct rte_intr_handle *intr_handle,
348 : : int index, int fd)
349 : : {
350 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
351 : :
352 [ # # ]: 0 : if (index >= intr_handle->nb_intr) {
353 : 0 : EAL_LOG(DEBUG, "Invalid index %d, max limit %d", index,
354 : : intr_handle->nb_intr);
355 : 0 : rte_errno = ERANGE;
356 : 0 : goto fail;
357 : : }
358 : :
359 : 0 : intr_handle->efds[index] = fd;
360 : :
361 : 0 : return 0;
362 : 0 : fail:
363 : 0 : return -rte_errno;
364 : : }
365 : :
366 : 0 : struct rte_epoll_event *rte_intr_elist_index_get(
367 : : struct rte_intr_handle *intr_handle, int index)
368 : : {
369 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
370 : :
371 [ # # ]: 0 : if (index >= intr_handle->nb_intr) {
372 : 0 : EAL_LOG(DEBUG, "Invalid index %d, max limit %d", index,
373 : : intr_handle->nb_intr);
374 : 0 : rte_errno = ERANGE;
375 : 0 : goto fail;
376 : : }
377 : :
378 : 0 : return &intr_handle->elist[index];
379 : : fail:
380 : : return NULL;
381 : : }
382 : :
383 : 0 : int rte_intr_elist_index_set(struct rte_intr_handle *intr_handle,
384 : : int index, struct rte_epoll_event elist)
385 : : {
386 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
387 : :
388 [ # # ]: 0 : if (index >= intr_handle->nb_intr) {
389 : 0 : EAL_LOG(DEBUG, "Invalid index %d, max limit %d", index,
390 : : intr_handle->nb_intr);
391 : 0 : rte_errno = ERANGE;
392 : 0 : goto fail;
393 : : }
394 : :
395 : 0 : intr_handle->elist[index] = elist;
396 : :
397 : 0 : return 0;
398 : 0 : fail:
399 : 0 : return -rte_errno;
400 : : }
401 : :
402 : 0 : int rte_intr_vec_list_alloc(struct rte_intr_handle *intr_handle,
403 : : const char *name, int size)
404 : : {
405 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
406 : :
407 : : /* Vector list already allocated */
408 [ # # ]: 0 : if (intr_handle->intr_vec != NULL)
409 : : return 0;
410 : :
411 [ # # ]: 0 : if (size > intr_handle->nb_intr) {
412 : 0 : EAL_LOG(DEBUG, "Invalid size %d, max limit %d", size,
413 : : intr_handle->nb_intr);
414 : 0 : rte_errno = ERANGE;
415 : 0 : goto fail;
416 : : }
417 : :
418 [ # # ]: 0 : if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
419 : 0 : intr_handle->intr_vec = rte_zmalloc(name, size * sizeof(int), 0);
420 : : else
421 : 0 : intr_handle->intr_vec = calloc(size, sizeof(int));
422 [ # # ]: 0 : if (intr_handle->intr_vec == NULL) {
423 : 0 : EAL_LOG(ERR, "Failed to allocate %d intr_vec", size);
424 : 0 : rte_errno = ENOMEM;
425 : 0 : goto fail;
426 : : }
427 : :
428 : 0 : intr_handle->vec_list_size = size;
429 : :
430 : 0 : return 0;
431 : 0 : fail:
432 : 0 : return -rte_errno;
433 : : }
434 : :
435 : 0 : int rte_intr_vec_list_index_get(const struct rte_intr_handle *intr_handle,
436 : : int index)
437 : : {
438 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
439 : :
440 [ # # ]: 0 : if (index >= intr_handle->vec_list_size) {
441 : 0 : EAL_LOG(DEBUG, "Index %d greater than vec list size %d",
442 : : index, intr_handle->vec_list_size);
443 : 0 : rte_errno = ERANGE;
444 : 0 : goto fail;
445 : : }
446 : :
447 : 0 : return intr_handle->intr_vec[index];
448 : 0 : fail:
449 : 0 : return -rte_errno;
450 : : }
451 : :
452 : 0 : int rte_intr_vec_list_index_set(struct rte_intr_handle *intr_handle,
453 : : int index, int vec)
454 : : {
455 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
456 : :
457 [ # # ]: 0 : if (index >= intr_handle->vec_list_size) {
458 : 0 : EAL_LOG(DEBUG, "Index %d greater than vec list size %d",
459 : : index, intr_handle->vec_list_size);
460 : 0 : rte_errno = ERANGE;
461 : 0 : goto fail;
462 : : }
463 : :
464 : 0 : intr_handle->intr_vec[index] = vec;
465 : :
466 : 0 : return 0;
467 : 0 : fail:
468 : 0 : return -rte_errno;
469 : : }
470 : :
471 : 0 : void rte_intr_vec_list_free(struct rte_intr_handle *intr_handle)
472 : : {
473 [ # # ]: 0 : if (intr_handle == NULL)
474 : : return;
475 [ # # ]: 0 : if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
476 : 0 : rte_free(intr_handle->intr_vec);
477 : : else
478 : 0 : free(intr_handle->intr_vec);
479 : 0 : intr_handle->intr_vec = NULL;
480 : 0 : intr_handle->vec_list_size = 0;
481 : : }
482 : :
483 : 0 : void *rte_intr_instance_windows_handle_get(struct rte_intr_handle *intr_handle)
484 : : {
485 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
486 : :
487 : 0 : return intr_handle->windows_handle;
488 : : fail:
489 : 0 : return NULL;
490 : : }
491 : :
492 : 0 : int rte_intr_instance_windows_handle_set(struct rte_intr_handle *intr_handle,
493 : : void *windows_handle)
494 : : {
495 [ # # ]: 0 : CHECK_VALID_INTR_HANDLE(intr_handle);
496 : :
497 : 0 : intr_handle->windows_handle = windows_handle;
498 : :
499 : 0 : return 0;
500 : : fail:
501 : 0 : return -rte_errno;
502 : : }
|