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