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