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