1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2021 Marvell.
9 #include <rte_interrupts.h>
11 #include <rte_malloc.h>
13 #include "eal_interrupts.h"
15 /* Macros to check for valid interrupt handle */
16 #define CHECK_VALID_INTR_HANDLE(intr_handle) do { \
17 if (intr_handle == NULL) { \
18 RTE_LOG(DEBUG, EAL, "Interrupt instance unallocated\n"); \
24 #define RTE_INTR_INSTANCE_KNOWN_FLAGS (RTE_INTR_INSTANCE_F_PRIVATE \
25 | RTE_INTR_INSTANCE_F_SHARED \
28 #define RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags) \
29 (!!(flags & RTE_INTR_INSTANCE_F_SHARED))
31 struct rte_intr_handle *rte_intr_instance_alloc(uint32_t flags)
33 struct rte_intr_handle *intr_handle;
36 /* Check the flag passed by user, it should be part of the
39 if ((flags & ~RTE_INTR_INSTANCE_KNOWN_FLAGS) != 0) {
40 RTE_LOG(DEBUG, EAL, "Invalid alloc flag passed 0x%x\n", flags);
45 uses_rte_memory = RTE_INTR_INSTANCE_USES_RTE_MEMORY(flags);
47 intr_handle = rte_zmalloc(NULL, sizeof(*intr_handle), 0);
49 intr_handle = calloc(1, sizeof(*intr_handle));
50 if (intr_handle == NULL) {
51 RTE_LOG(ERR, EAL, "Failed to allocate intr_handle\n");
56 if (uses_rte_memory) {
57 intr_handle->efds = rte_zmalloc(NULL,
58 RTE_MAX_RXTX_INTR_VEC_ID * sizeof(int), 0);
60 intr_handle->efds = calloc(RTE_MAX_RXTX_INTR_VEC_ID,
63 if (intr_handle->efds == NULL) {
64 RTE_LOG(ERR, EAL, "Fail to allocate event fd list\n");
69 if (uses_rte_memory) {
70 intr_handle->elist = rte_zmalloc(NULL,
71 RTE_MAX_RXTX_INTR_VEC_ID * sizeof(struct rte_epoll_event),
74 intr_handle->elist = calloc(RTE_MAX_RXTX_INTR_VEC_ID,
75 sizeof(struct rte_epoll_event));
77 if (intr_handle->elist == NULL) {
78 RTE_LOG(ERR, EAL, "fail to allocate event fd list\n");
83 intr_handle->alloc_flags = flags;
84 intr_handle->nb_intr = RTE_MAX_RXTX_INTR_VEC_ID;
88 if (uses_rte_memory) {
89 rte_free(intr_handle->efds);
90 rte_free(intr_handle);
92 free(intr_handle->efds);
98 struct rte_intr_handle *rte_intr_instance_dup(const struct rte_intr_handle *src)
100 struct rte_intr_handle *intr_handle;
103 RTE_LOG(DEBUG, EAL, "Source interrupt instance unallocated\n");
108 intr_handle = rte_intr_instance_alloc(src->alloc_flags);
109 if (intr_handle != NULL) {
110 intr_handle->fd = src->fd;
111 intr_handle->dev_fd = src->dev_fd;
112 intr_handle->type = src->type;
113 intr_handle->max_intr = src->max_intr;
114 intr_handle->nb_efd = src->nb_efd;
115 intr_handle->efd_counter_size = src->efd_counter_size;
116 memcpy(intr_handle->efds, src->efds, src->nb_intr);
117 memcpy(intr_handle->elist, src->elist, src->nb_intr);
123 int rte_intr_event_list_update(struct rte_intr_handle *intr_handle, int size)
125 struct rte_epoll_event *tmp_elist;
126 bool uses_rte_memory;
129 CHECK_VALID_INTR_HANDLE(intr_handle);
132 RTE_LOG(DEBUG, EAL, "Size can't be zero\n");
138 RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags);
139 if (uses_rte_memory) {
140 tmp_efds = rte_realloc(intr_handle->efds, size * sizeof(int),
143 tmp_efds = realloc(intr_handle->efds, size * sizeof(int));
145 if (tmp_efds == NULL) {
146 RTE_LOG(ERR, EAL, "Failed to realloc the efds list\n");
150 intr_handle->efds = tmp_efds;
152 if (uses_rte_memory) {
153 tmp_elist = rte_realloc(intr_handle->elist,
154 size * sizeof(struct rte_epoll_event), 0);
156 tmp_elist = realloc(intr_handle->elist,
157 size * sizeof(struct rte_epoll_event));
159 if (tmp_elist == NULL) {
160 RTE_LOG(ERR, EAL, "Failed to realloc the event list\n");
164 intr_handle->elist = tmp_elist;
166 intr_handle->nb_intr = size;
173 void rte_intr_instance_free(struct rte_intr_handle *intr_handle)
175 if (intr_handle == NULL)
177 if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags)) {
178 rte_free(intr_handle->efds);
179 rte_free(intr_handle->elist);
180 rte_free(intr_handle);
182 free(intr_handle->efds);
183 free(intr_handle->elist);
188 int rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd)
190 CHECK_VALID_INTR_HANDLE(intr_handle);
192 intr_handle->fd = fd;
199 int rte_intr_fd_get(const struct rte_intr_handle *intr_handle)
201 CHECK_VALID_INTR_HANDLE(intr_handle);
203 return intr_handle->fd;
208 int rte_intr_type_set(struct rte_intr_handle *intr_handle,
209 enum rte_intr_handle_type type)
211 CHECK_VALID_INTR_HANDLE(intr_handle);
213 intr_handle->type = type;
220 enum rte_intr_handle_type rte_intr_type_get(
221 const struct rte_intr_handle *intr_handle)
223 CHECK_VALID_INTR_HANDLE(intr_handle);
225 return intr_handle->type;
227 return RTE_INTR_HANDLE_UNKNOWN;
230 int rte_intr_dev_fd_set(struct rte_intr_handle *intr_handle, int fd)
232 CHECK_VALID_INTR_HANDLE(intr_handle);
234 intr_handle->dev_fd = fd;
241 int rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle)
243 CHECK_VALID_INTR_HANDLE(intr_handle);
245 return intr_handle->dev_fd;
250 int rte_intr_max_intr_set(struct rte_intr_handle *intr_handle,
253 CHECK_VALID_INTR_HANDLE(intr_handle);
255 if (max_intr > intr_handle->nb_intr) {
256 RTE_LOG(DEBUG, EAL, "Maximum interrupt vector ID (%d) exceeds "
257 "the number of available events (%d)\n", max_intr,
258 intr_handle->nb_intr);
263 intr_handle->max_intr = max_intr;
270 int rte_intr_max_intr_get(const struct rte_intr_handle *intr_handle)
272 CHECK_VALID_INTR_HANDLE(intr_handle);
274 return intr_handle->max_intr;
279 int rte_intr_nb_efd_set(struct rte_intr_handle *intr_handle, int nb_efd)
281 CHECK_VALID_INTR_HANDLE(intr_handle);
283 intr_handle->nb_efd = nb_efd;
290 int rte_intr_nb_efd_get(const struct rte_intr_handle *intr_handle)
292 CHECK_VALID_INTR_HANDLE(intr_handle);
294 return intr_handle->nb_efd;
299 int rte_intr_nb_intr_get(const struct rte_intr_handle *intr_handle)
301 CHECK_VALID_INTR_HANDLE(intr_handle);
303 return intr_handle->nb_intr;
308 int rte_intr_efd_counter_size_set(struct rte_intr_handle *intr_handle,
309 uint8_t efd_counter_size)
311 CHECK_VALID_INTR_HANDLE(intr_handle);
313 intr_handle->efd_counter_size = efd_counter_size;
320 int rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle)
322 CHECK_VALID_INTR_HANDLE(intr_handle);
324 return intr_handle->efd_counter_size;
329 int rte_intr_efds_index_get(const struct rte_intr_handle *intr_handle,
332 CHECK_VALID_INTR_HANDLE(intr_handle);
334 if (index >= intr_handle->nb_intr) {
335 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
336 intr_handle->nb_intr);
341 return intr_handle->efds[index];
346 int rte_intr_efds_index_set(struct rte_intr_handle *intr_handle,
349 CHECK_VALID_INTR_HANDLE(intr_handle);
351 if (index >= intr_handle->nb_intr) {
352 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
353 intr_handle->nb_intr);
358 intr_handle->efds[index] = fd;
365 struct rte_epoll_event *rte_intr_elist_index_get(
366 struct rte_intr_handle *intr_handle, int index)
368 CHECK_VALID_INTR_HANDLE(intr_handle);
370 if (index >= intr_handle->nb_intr) {
371 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
372 intr_handle->nb_intr);
377 return &intr_handle->elist[index];
382 int rte_intr_elist_index_set(struct rte_intr_handle *intr_handle,
383 int index, struct rte_epoll_event elist)
385 CHECK_VALID_INTR_HANDLE(intr_handle);
387 if (index >= intr_handle->nb_intr) {
388 RTE_LOG(DEBUG, EAL, "Invalid index %d, max limit %d\n", index,
389 intr_handle->nb_intr);
394 intr_handle->elist[index] = elist;
401 int rte_intr_vec_list_alloc(struct rte_intr_handle *intr_handle,
402 const char *name, int size)
404 CHECK_VALID_INTR_HANDLE(intr_handle);
406 /* Vector list already allocated */
407 if (intr_handle->intr_vec != NULL)
410 if (size > intr_handle->nb_intr) {
411 RTE_LOG(DEBUG, EAL, "Invalid size %d, max limit %d\n", size,
412 intr_handle->nb_intr);
417 if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
418 intr_handle->intr_vec = rte_zmalloc(name, size * sizeof(int), 0);
420 intr_handle->intr_vec = calloc(size, sizeof(int));
421 if (intr_handle->intr_vec == NULL) {
422 RTE_LOG(ERR, EAL, "Failed to allocate %d intr_vec\n", size);
427 intr_handle->vec_list_size = size;
434 int rte_intr_vec_list_index_get(const struct rte_intr_handle *intr_handle,
437 CHECK_VALID_INTR_HANDLE(intr_handle);
439 if (index >= intr_handle->vec_list_size) {
440 RTE_LOG(DEBUG, EAL, "Index %d greater than vec list size %d\n",
441 index, intr_handle->vec_list_size);
446 return intr_handle->intr_vec[index];
451 int rte_intr_vec_list_index_set(struct rte_intr_handle *intr_handle,
454 CHECK_VALID_INTR_HANDLE(intr_handle);
456 if (index >= intr_handle->vec_list_size) {
457 RTE_LOG(DEBUG, EAL, "Index %d greater than vec list size %d\n",
458 index, intr_handle->vec_list_size);
463 intr_handle->intr_vec[index] = vec;
470 void rte_intr_vec_list_free(struct rte_intr_handle *intr_handle)
472 if (intr_handle == NULL)
474 if (RTE_INTR_INSTANCE_USES_RTE_MEMORY(intr_handle->alloc_flags))
475 rte_free(intr_handle->intr_vec);
477 free(intr_handle->intr_vec);
478 intr_handle->intr_vec = NULL;
479 intr_handle->vec_list_size = 0;
482 void *rte_intr_instance_windows_handle_get(struct rte_intr_handle *intr_handle)
484 CHECK_VALID_INTR_HANDLE(intr_handle);
486 return intr_handle->windows_handle;
491 int rte_intr_instance_windows_handle_set(struct rte_intr_handle *intr_handle,
492 void *windows_handle)
494 CHECK_VALID_INTR_HANDLE(intr_handle);
496 intr_handle->windows_handle = windows_handle;