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