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