interrupts: extend event list
[dpdk.git] / lib / eal / include / rte_interrupts.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #ifndef _RTE_INTERRUPTS_H_
6 #define _RTE_INTERRUPTS_H_
7
8 #include <stdbool.h>
9
10 #include <rte_bitops.h>
11 #include <rte_common.h>
12 #include <rte_compat.h>
13 #include <rte_epoll.h>
14
15 /**
16  * @file
17  *
18  * The RTE interrupt interface provides functions to register/unregister
19  * callbacks for a specific interrupt.
20  */
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 /** Interrupt handle */
27 struct rte_intr_handle;
28
29 /** Interrupt instance allocation flags
30  * @see rte_intr_instance_alloc
31  */
32
33 /** Interrupt instance will not be shared between primary and secondary processes. */
34 #define RTE_INTR_INSTANCE_F_PRIVATE     UINT32_C(0)
35 /** Interrupt instance will be shared between primary and secondary processes. */
36 #define RTE_INTR_INSTANCE_F_SHARED      RTE_BIT32(0)
37
38 #define RTE_MAX_RXTX_INTR_VEC_ID      512
39 #define RTE_INTR_VEC_ZERO_OFFSET      0
40 #define RTE_INTR_VEC_RXTX_OFFSET      1
41
42 /**
43  * The interrupt source type, e.g. UIO, VFIO, ALARM etc.
44  */
45 enum rte_intr_handle_type {
46         RTE_INTR_HANDLE_UNKNOWN = 0,  /**< generic unknown handle */
47         RTE_INTR_HANDLE_UIO,          /**< uio device handle */
48         RTE_INTR_HANDLE_UIO_INTX,     /**< uio generic handle */
49         RTE_INTR_HANDLE_VFIO_LEGACY,  /**< vfio device handle (legacy) */
50         RTE_INTR_HANDLE_VFIO_MSI,     /**< vfio device handle (MSI) */
51         RTE_INTR_HANDLE_VFIO_MSIX,    /**< vfio device handle (MSIX) */
52         RTE_INTR_HANDLE_ALARM,        /**< alarm handle */
53         RTE_INTR_HANDLE_EXT,          /**< external handler */
54         RTE_INTR_HANDLE_VDEV,         /**< virtual device */
55         RTE_INTR_HANDLE_DEV_EVENT,    /**< device event handle */
56         RTE_INTR_HANDLE_VFIO_REQ,     /**< VFIO request handle */
57         RTE_INTR_HANDLE_MAX           /**< count of elements */
58 };
59
60 /** Function to be registered for the specific interrupt */
61 typedef void (*rte_intr_callback_fn)(void *cb_arg);
62
63 /**
64  * Function to call after a callback is unregistered.
65  * Can be used to close fd and free cb_arg.
66  */
67 typedef void (*rte_intr_unregister_callback_fn)(struct rte_intr_handle *intr_handle,
68                                                 void *cb_arg);
69
70 /**
71  * It registers the callback for the specific interrupt. Multiple
72  * callbacks can be registered at the same time.
73  * @param intr_handle
74  *  Pointer to the interrupt handle.
75  * @param cb
76  *  callback address.
77  * @param cb_arg
78  *  address of parameter for callback.
79  *
80  * @return
81  *  - On success, zero.
82  *  - On failure, a negative value.
83  */
84 int rte_intr_callback_register(const struct rte_intr_handle *intr_handle,
85                                 rte_intr_callback_fn cb, void *cb_arg);
86
87 /**
88  * It unregisters the callback according to the specified interrupt handle.
89  *
90  * @param intr_handle
91  *  pointer to the interrupt handle.
92  * @param cb
93  *  callback address.
94  * @param cb_arg
95  *  address of parameter for callback, (void *)-1 means to remove all
96  *  registered which has the same callback address.
97  *
98  * @return
99  *  - On success, return the number of callback entities removed.
100  *  - On failure, a negative value.
101  */
102 int rte_intr_callback_unregister(const struct rte_intr_handle *intr_handle,
103                                 rte_intr_callback_fn cb, void *cb_arg);
104
105 /**
106  * Unregister the callback according to the specified interrupt handle,
107  * after it's no longer active. Fail if source is not active.
108  *
109  * @param intr_handle
110  *  pointer to the interrupt handle.
111  * @param cb_fn
112  *  callback address.
113  * @param cb_arg
114  *  address of parameter for callback, (void *)-1 means to remove all
115  *  registered which has the same callback address.
116  * @param ucb_fn
117  *  callback to call before cb is unregistered (optional).
118  *  can be used to close fd and free cb_arg.
119  *
120  * @return
121  *  - On success, return the number of callback entities marked for remove.
122  *  - On failure, a negative value.
123  */
124 __rte_experimental
125 int
126 rte_intr_callback_unregister_pending(const struct rte_intr_handle *intr_handle,
127                                 rte_intr_callback_fn cb_fn, void *cb_arg,
128                                 rte_intr_unregister_callback_fn ucb_fn);
129
130 /**
131  * @warning
132  * @b EXPERIMENTAL: this API may change without prior notice
133  *
134  * Loop until rte_intr_callback_unregister() succeeds.
135  * After a call to this function,
136  * the callback provided by the specified interrupt handle is unregistered.
137  *
138  * @param intr_handle
139  *  pointer to the interrupt handle.
140  * @param cb
141  *  callback address.
142  * @param cb_arg
143  *  address of parameter for callback, (void *)-1 means to remove all
144  *  registered which has the same callback address.
145  *
146  * @return
147  *  - On success, return the number of callback entities removed.
148  *  - On failure, a negative value.
149  */
150 __rte_experimental
151 int
152 rte_intr_callback_unregister_sync(const struct rte_intr_handle *intr_handle,
153                                 rte_intr_callback_fn cb, void *cb_arg);
154
155 /**
156  * It enables the interrupt for the specified handle.
157  *
158  * @param intr_handle
159  *  pointer to the interrupt handle.
160  *
161  * @return
162  *  - On success, zero.
163  *  - On failure, a negative value.
164  */
165 int rte_intr_enable(const struct rte_intr_handle *intr_handle);
166
167 /**
168  * It disables the interrupt for the specified handle.
169  *
170  * @param intr_handle
171  *  pointer to the interrupt handle.
172  *
173  * @return
174  *  - On success, zero.
175  *  - On failure, a negative value.
176  */
177 int rte_intr_disable(const struct rte_intr_handle *intr_handle);
178
179 /**
180  * @warning
181  * @b EXPERIMENTAL: this API may change without prior notice
182  *
183  * It acknowledges an interrupt raised for the specified handle.
184  *
185  * This function should be called at the end of each interrupt handler either
186  * from application or driver, so that currently raised interrupt is acked and
187  * further new interrupts are raised.
188  *
189  * @param intr_handle
190  *  pointer to the interrupt handle.
191  *
192  * @return
193  *  - On success, zero.
194  *  - On failure, a negative value.
195  */
196 __rte_experimental
197 int rte_intr_ack(const struct rte_intr_handle *intr_handle);
198
199 /**
200  * @warning
201  * @b EXPERIMENTAL: this API may change without prior notice
202  *
203  * Check if currently executing in interrupt context
204  *
205  * @return
206  *  - non zero in case of interrupt context
207  *  - zero in case of process context
208  */
209 __rte_experimental
210 int
211 rte_thread_is_intr(void);
212
213 /**
214  * @warning
215  * @b EXPERIMENTAL: this API may change without prior notice
216  *
217  * It allocates memory for interrupt instance. API takes flag as an argument
218  * which define from where memory should be allocated i.e. using DPDK memory
219  * management library APIs or normal heap allocation.
220  * Default memory allocation for event fds and event list array is done which
221  * can be realloced later based on size of MSIX interrupts supported by a PCI
222  * device.
223  *
224  * This function should be called from application or driver, before calling
225  * any of the interrupt APIs.
226  *
227  * @param flags
228  *  See RTE_INTR_INSTANCE_F_* flags definitions.
229  *
230  * @return
231  *  - On success, address of interrupt handle.
232  *  - On failure, NULL.
233  */
234 __rte_experimental
235 struct rte_intr_handle *
236 rte_intr_instance_alloc(uint32_t flags);
237
238 /**
239  * @warning
240  * @b EXPERIMENTAL: this API may change without prior notice
241  *
242  * This API is used to free the memory allocated for interrupt handle
243  * resources.
244  *
245  * @param intr_handle
246  *  Interrupt handle address.
247  *
248  */
249 __rte_experimental
250 void
251 rte_intr_instance_free(struct rte_intr_handle *intr_handle);
252
253 /**
254  * @warning
255  * @b EXPERIMENTAL: this API may change without prior notice
256  *
257  * This API is used to set the fd field of interrupt handle with user provided
258  * file descriptor.
259  *
260  * @param intr_handle
261  *  pointer to the interrupt handle.
262  * @param fd
263  *  file descriptor value provided by user.
264  *
265  * @return
266  *  - On success, zero.
267  *  - On failure, a negative value and rte_errno is set.
268  */
269 __rte_experimental
270 int
271 rte_intr_fd_set(struct rte_intr_handle *intr_handle, int fd);
272
273 /**
274  * @warning
275  * @b EXPERIMENTAL: this API may change without prior notice
276  *
277  * Returns the fd field of the given interrupt handle instance.
278  *
279  * @param intr_handle
280  *  pointer to the interrupt handle.
281  *
282  * @return
283  *  - On success, fd field.
284  *  - On failure, a negative value.
285  */
286 __rte_experimental
287 int
288 rte_intr_fd_get(const struct rte_intr_handle *intr_handle);
289
290 /**
291  * @warning
292  * @b EXPERIMENTAL: this API may change without prior notice
293  *
294  * This API is used to set the type field of interrupt handle with user provided
295  * interrupt type.
296  *
297  * @param intr_handle
298  *  pointer to the interrupt handle.
299  * @param type
300  *  interrupt type
301  *
302  * @return
303  *  - On success, zero.
304  *  - On failure, a negative value and rte_errno is set.
305  */
306 __rte_experimental
307 int
308 rte_intr_type_set(struct rte_intr_handle *intr_handle,
309                   enum rte_intr_handle_type type);
310
311 /**
312  * @warning
313  * @b EXPERIMENTAL: this API may change without prior notice
314  *
315  * Returns the type field of the given interrupt handle instance.
316  *
317  * @param intr_handle
318  *  pointer to the interrupt handle.
319  *
320  * @return
321  *  - On success, interrupt type
322  *  - On failure, RTE_INTR_HANDLE_UNKNOWN.
323  */
324 __rte_experimental
325 enum rte_intr_handle_type
326 rte_intr_type_get(const struct rte_intr_handle *intr_handle);
327
328 /**
329  * @internal
330  * The function returns the per thread epoll instance.
331  *
332  * @return
333  *   epfd the epoll instance referred to.
334  */
335 __rte_internal
336 int
337 rte_intr_tls_epfd(void);
338
339 /**
340  * @internal
341  * @param intr_handle
342  *   Pointer to the interrupt handle.
343  * @param epfd
344  *   Epoll instance fd which the intr vector associated to.
345  * @param op
346  *   The operation be performed for the vector.
347  *   Operation type of {ADD, DEL}.
348  * @param vec
349  *   RX intr vector number added to the epoll instance wait list.
350  * @param data
351  *   User raw data.
352  * @return
353  *   - On success, zero.
354  *   - On failure, a negative value.
355  */
356 __rte_internal
357 int
358 rte_intr_rx_ctl(struct rte_intr_handle *intr_handle,
359                 int epfd, int op, unsigned int vec, void *data);
360
361 /**
362  * @internal
363  * It deletes registered eventfds.
364  *
365  * @param intr_handle
366  *   Pointer to the interrupt handle.
367  */
368 __rte_internal
369 void
370 rte_intr_free_epoll_fd(struct rte_intr_handle *intr_handle);
371
372 /**
373  * @internal
374  * It enables the packet I/O interrupt event if it's necessary.
375  * It creates event fd for each interrupt vector when MSIX is used,
376  * otherwise it multiplexes a single event fd.
377  *
378  * @param intr_handle
379  *   Pointer to the interrupt handle.
380  * @param nb_efd
381  *   Number of interrupt vector trying to enable.
382  *   The value 0 is not allowed.
383  * @return
384  *   - On success, zero.
385  *   - On failure, a negative value.
386  */
387 __rte_internal
388 int
389 rte_intr_efd_enable(struct rte_intr_handle *intr_handle, uint32_t nb_efd);
390
391 /**
392  * @internal
393  * It disables the packet I/O interrupt event.
394  * It deletes registered eventfds and closes the open fds.
395  *
396  * @param intr_handle
397  *   Pointer to the interrupt handle.
398  */
399 __rte_internal
400 void
401 rte_intr_efd_disable(struct rte_intr_handle *intr_handle);
402
403 /**
404  * @internal
405  * The packet I/O interrupt on datapath is enabled or not.
406  *
407  * @param intr_handle
408  *   Pointer to the interrupt handle.
409  */
410 __rte_internal
411 int
412 rte_intr_dp_is_en(struct rte_intr_handle *intr_handle);
413
414 /**
415  * @internal
416  * The interrupt handle instance allows other causes or not.
417  * Other causes stand for any none packet I/O interrupts.
418  *
419  * @param intr_handle
420  *   Pointer to the interrupt handle.
421  */
422 __rte_internal
423 int
424 rte_intr_allow_others(struct rte_intr_handle *intr_handle);
425
426 /**
427  * @internal
428  * The multiple interrupt vector capability of interrupt handle instance.
429  * It returns zero if no multiple interrupt vector support.
430  *
431  * @param intr_handle
432  *   Pointer to the interrupt handle.
433  */
434 __rte_internal
435 int
436 rte_intr_cap_multiple(struct rte_intr_handle *intr_handle);
437
438 /**
439  * @internal
440  * Creates a clone of src by allocating a new handle and copying src content.
441  *
442  * @param src
443  *  Source interrupt handle to be cloned.
444  *
445  * @return
446  *  - On success, address of interrupt handle.
447  *  - On failure, NULL.
448  */
449 __rte_internal
450 struct rte_intr_handle *
451 rte_intr_instance_dup(const struct rte_intr_handle *src);
452
453 /**
454  * @internal
455  * This API is used to set the device fd field of interrupt handle with user
456  * provided dev fd. Device fd corresponds to VFIO device fd or UIO config fd.
457  *
458  * @param intr_handle
459  *  pointer to the interrupt handle.
460  * @param fd
461  *  interrupt type
462  *
463  * @return
464  *  - On success, zero.
465  *  - On failure, a negative value and rte_errno is set.
466  */
467 __rte_internal
468 int
469 rte_intr_dev_fd_set(struct rte_intr_handle *intr_handle, int fd);
470
471 /**
472  * @internal
473  * Returns the device fd field of the given interrupt handle instance.
474  *
475  * @param intr_handle
476  *  pointer to the interrupt handle.
477  *
478  * @return
479  *  - On success, dev fd.
480  *  - On failure, a negative value and rte_errno is set.
481  */
482 __rte_internal
483 int
484 rte_intr_dev_fd_get(const struct rte_intr_handle *intr_handle);
485
486 /**
487  * @internal
488  * This API is used to set the max intr field of interrupt handle with user
489  * provided max intr value.
490  *
491  * @param intr_handle
492  *  pointer to the interrupt handle.
493  * @param max_intr
494  *  interrupt type
495  *
496  * @return
497  *  - On success, zero.
498  *  - On failure, a negative value and rte_errno is set.
499  */
500 __rte_internal
501 int
502 rte_intr_max_intr_set(struct rte_intr_handle *intr_handle, int max_intr);
503
504 /**
505  * @internal
506  * Returns the max intr field of the given interrupt handle instance.
507  *
508  * @param intr_handle
509  *  pointer to the interrupt handle.
510  *
511  * @return
512  *  - On success, max intr.
513  *  - On failure, a negative value and rte_errno is set.
514  */
515 __rte_internal
516 int
517 rte_intr_max_intr_get(const struct rte_intr_handle *intr_handle);
518
519 /**
520  * @internal
521  * This API is used to set the number of event fd field of interrupt handle
522  * with user provided available event file descriptor value.
523  *
524  * @param intr_handle
525  *  pointer to the interrupt handle.
526  * @param nb_efd
527  *  Available event fd
528  *
529  * @return
530  *  - On success, zero.
531  *  - On failure, a negative value and rte_errno is set.
532  */
533 __rte_internal
534 int
535 rte_intr_nb_efd_set(struct rte_intr_handle *intr_handle, int nb_efd);
536
537 /**
538  * @internal
539  * Returns the number of available event fd field of the given interrupt handle
540  * instance.
541  *
542  * @param intr_handle
543  *  pointer to the interrupt handle.
544  *
545  * @return
546  *  - On success, nb_efd
547  *  - On failure, a negative value and rte_errno is set.
548  */
549 __rte_internal
550 int
551 rte_intr_nb_efd_get(const struct rte_intr_handle *intr_handle);
552
553 /**
554  * @internal
555  * Returns the number of interrupt vector field of the given interrupt handle
556  * instance. This field is to configured on device probe time, and based on
557  * this value efds and elist arrays are dynamically allocated. By default
558  * this value is set to RTE_MAX_RXTX_INTR_VEC_ID.
559  * For eg. in case of PCI device, its msix size is queried and efds/elist
560  * arrays are allocated accordingly.
561  *
562  * @param intr_handle
563  *  pointer to the interrupt handle.
564  *
565  * @return
566  *  - On success, nb_intr
567  *  - On failure, a negative value and rte_errno is set.
568  */
569 __rte_internal
570 int
571 rte_intr_nb_intr_get(const struct rte_intr_handle *intr_handle);
572
573 /**
574  * @internal
575  * This API is used to set the event fd counter size field of interrupt handle
576  * with user provided efd counter size.
577  *
578  * @param intr_handle
579  *  pointer to the interrupt handle.
580  * @param efd_counter_size
581  *  size of efd counter.
582  *
583  * @return
584  *  - On success, zero.
585  *  - On failure, a negative value and rte_errno is set.
586  */
587 __rte_internal
588 int
589 rte_intr_efd_counter_size_set(struct rte_intr_handle *intr_handle,
590                               uint8_t efd_counter_size);
591
592 /**
593  * @internal
594  * Returns the event fd counter size field of the given interrupt handle
595  * instance.
596  *
597  * @param intr_handle
598  *  pointer to the interrupt handle.
599  *
600  * @return
601  *  - On success, efd_counter_size
602  *  - On failure, a negative value and rte_errno is set.
603  */
604 __rte_internal
605 int
606 rte_intr_efd_counter_size_get(const struct rte_intr_handle *intr_handle);
607
608 /**
609  * @internal
610  * This API is used to set the event fd array index with the given fd.
611  *
612  * @param intr_handle
613  *  pointer to the interrupt handle.
614  * @param index
615  *  efds array index to be set
616  * @param fd
617  *  event fd
618  *
619  * @return
620  *  - On success, zero.
621  *  - On failure, a negative value and rte_errno is set.
622  */
623 __rte_internal
624 int
625 rte_intr_efds_index_set(struct rte_intr_handle *intr_handle, int index, int fd);
626
627 /**
628  * @internal
629  * Returns the fd value of event fds array at a given index.
630  *
631  * @param intr_handle
632  *  pointer to the interrupt handle.
633  * @param index
634  *  efds array index to be returned
635  *
636  * @return
637  *  - On success, fd
638  *  - On failure, a negative value and rte_errno is set.
639  */
640 __rte_internal
641 int
642 rte_intr_efds_index_get(const struct rte_intr_handle *intr_handle, int index);
643
644 /**
645  * @internal
646  * This API is used to set the epoll event object array index with the given
647  * elist instance.
648  *
649  * @param intr_handle
650  *  pointer to the interrupt handle.
651  * @param index
652  *  elist array index to be set
653  * @param elist
654  *  epoll event instance of struct rte_epoll_event
655  *
656  * @return
657  *  - On success, zero.
658  *  - On failure, a negative value and rte_errno is set.
659  */
660 __rte_internal
661 int
662 rte_intr_elist_index_set(struct rte_intr_handle *intr_handle, int index,
663                          struct rte_epoll_event elist);
664
665 /**
666  * @internal
667  * Returns the address of epoll event instance from elist array at a given
668  * index.
669  *
670  * @param intr_handle
671  *  pointer to the interrupt handle.
672  * @param index
673  *  elist array index to be returned
674  *
675  * @return
676  *  - On success, elist
677  *  - On failure, a negative value and rte_errno is set.
678  */
679 __rte_internal
680 struct rte_epoll_event *
681 rte_intr_elist_index_get(struct rte_intr_handle *intr_handle, int index);
682
683 /**
684  * @internal
685  * Allocates the memory of interrupt vector list array, with size defining the
686  * number of elements required in the array.
687  *
688  * @param intr_handle
689  *  pointer to the interrupt handle.
690  * @param name
691  *  Name assigned to the allocation, or NULL.
692  * @param size
693  *  Number of element required in the array.
694  *
695  * @return
696  *  - On success, zero
697  *  - On failure, a negative value and rte_errno is set.
698  */
699 __rte_internal
700 int
701 rte_intr_vec_list_alloc(struct rte_intr_handle *intr_handle, const char *name,
702                         int size);
703
704 /**
705  * @internal
706  * Sets the vector value at given index of interrupt vector list field of given
707  * interrupt handle.
708  *
709  * @param intr_handle
710  *  pointer to the interrupt handle.
711  * @param index
712  *  intr_vec array index to be set
713  * @param vec
714  *  Interrupt vector value.
715  *
716  * @return
717  *  - On success, zero
718  *  - On failure, a negative value and rte_errno is set.
719  */
720 __rte_internal
721 int
722 rte_intr_vec_list_index_set(struct rte_intr_handle *intr_handle, int index,
723                             int vec);
724
725 /**
726  * @internal
727  * Returns the vector value at the given index of interrupt vector list array.
728  *
729  * @param intr_handle
730  *  pointer to the interrupt handle.
731  * @param index
732  *  intr_vec array index to be returned
733  *
734  * @return
735  *  - On success, interrupt vector
736  *  - On failure, a negative value and rte_errno is set.
737  */
738 __rte_internal
739 int
740 rte_intr_vec_list_index_get(const struct rte_intr_handle *intr_handle,
741                             int index);
742
743 /**
744  * @internal
745  * Frees the memory allocated for interrupt vector list array.
746  *
747  * @param intr_handle
748  *  pointer to the interrupt handle.
749  *
750  * @return
751  *  - On success, zero
752  *  - On failure, a negative value and rte_errno is set.
753  */
754 __rte_internal
755 void
756 rte_intr_vec_list_free(struct rte_intr_handle *intr_handle);
757
758 /**
759  * @internal
760  * Reallocates the size efds and elist array based on size provided by user.
761  * By default efds and elist array are allocated with default size
762  * RTE_MAX_RXTX_INTR_VEC_ID on interrupt handle array creation. Later on device
763  * probe, device may have capability of more interrupts than
764  * RTE_MAX_RXTX_INTR_VEC_ID. Using this API, PMDs can reallocate the arrays as
765  * per the max interrupts capability of device.
766  *
767  * @param intr_handle
768  *  pointer to the interrupt handle.
769  * @param size
770  *  efds and elist array size.
771  *
772  * @return
773  *  - On success, zero
774  *  - On failure, a negative value and rte_errno is set.
775  */
776 __rte_internal
777 int
778 rte_intr_event_list_update(struct rte_intr_handle *intr_handle, int size);
779
780 /**
781  * @internal
782  * This API returns the Windows handle of the given interrupt instance.
783  *
784  * @param intr_handle
785  *  pointer to the interrupt handle.
786  *
787  * @return
788  *  - On success, Windows handle.
789  *  - On failure, NULL.
790  */
791 __rte_internal
792 void *
793 rte_intr_instance_windows_handle_get(struct rte_intr_handle *intr_handle);
794
795 /**
796  * @internal
797  * This API set the Windows handle for the given interrupt instance.
798  *
799  * @param intr_handle
800  *  pointer to the interrupt handle.
801  * @param windows_handle
802  *  Windows handle to be set.
803  *
804  * @return
805  *  - On success, zero
806  *  - On failure, a negative value and rte_errno is set.
807  */
808 __rte_internal
809 int
810 rte_intr_instance_windows_handle_set(struct rte_intr_handle *intr_handle,
811                                      void *windows_handle);
812
813 #ifdef __cplusplus
814 }
815 #endif
816
817 #endif