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