1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2014 Intel Corporation 3 */ 4 5 #ifndef _RTE_MEMORY_H_ 6 #define _RTE_MEMORY_H_ 7 8 /** 9 * @file 10 * 11 * Memory-related RTE API. 12 */ 13 14 #include <stdint.h> 15 #include <stddef.h> 16 #include <stdio.h> 17 18 #ifdef __cplusplus 19 extern "C" { 20 #endif 21 22 #include <rte_common.h> 23 #include <rte_compat.h> 24 #include <rte_config.h> 25 #include <rte_fbarray.h> 26 27 #define RTE_PGSIZE_4K (1ULL << 12) 28 #define RTE_PGSIZE_64K (1ULL << 16) 29 #define RTE_PGSIZE_256K (1ULL << 18) 30 #define RTE_PGSIZE_2M (1ULL << 21) 31 #define RTE_PGSIZE_16M (1ULL << 24) 32 #define RTE_PGSIZE_256M (1ULL << 28) 33 #define RTE_PGSIZE_512M (1ULL << 29) 34 #define RTE_PGSIZE_1G (1ULL << 30) 35 #define RTE_PGSIZE_4G (1ULL << 32) 36 #define RTE_PGSIZE_16G (1ULL << 34) 37 38 #define SOCKET_ID_ANY -1 /**< Any NUMA socket. */ 39 40 /** 41 * Physical memory segment descriptor. 42 */ 43 #define RTE_MEMSEG_FLAG_DO_NOT_FREE (1 << 0) 44 /**< Prevent this segment from being freed back to the OS. */ 45 struct rte_memseg { 46 rte_iova_t iova; /**< Start IO address. */ 47 RTE_STD_C11 48 union { 49 void *addr; /**< Start virtual address. */ 50 uint64_t addr_64; /**< Makes sure addr is always 64 bits */ 51 }; 52 size_t len; /**< Length of the segment. */ 53 uint64_t hugepage_sz; /**< The pagesize of underlying memory */ 54 int32_t socket_id; /**< NUMA socket ID. */ 55 uint32_t nchannel; /**< Number of channels. */ 56 uint32_t nrank; /**< Number of ranks. */ 57 uint32_t flags; /**< Memseg-specific flags */ 58 } __rte_packed; 59 60 /** 61 * memseg list is a special case as we need to store a bunch of other data 62 * together with the array itself. 63 */ 64 struct rte_memseg_list { 65 RTE_STD_C11 66 union { 67 void *base_va; 68 /**< Base virtual address for this memseg list. */ 69 uint64_t addr_64; 70 /**< Makes sure addr is always 64-bits */ 71 }; 72 uint64_t page_sz; /**< Page size for all memsegs in this list. */ 73 int socket_id; /**< Socket ID for all memsegs in this list. */ 74 volatile uint32_t version; /**< version number for multiprocess sync. */ 75 size_t len; /**< Length of memory area covered by this memseg list. */ 76 unsigned int external; /**< 1 if this list points to external memory */ 77 unsigned int heap; /**< 1 if this list points to a heap */ 78 struct rte_fbarray memseg_arr; 79 }; 80 81 /** 82 * Lock page in physical memory and prevent from swapping. 83 * 84 * @param virt 85 * The virtual address. 86 * @return 87 * 0 on success, negative on error. 88 */ 89 int rte_mem_lock_page(const void *virt); 90 91 /** 92 * Get physical address of any mapped virtual address in the current process. 93 * It is found by browsing the /proc/self/pagemap special file. 94 * The page must be locked. 95 * 96 * @param virt 97 * The virtual address. 98 * @return 99 * The physical address or RTE_BAD_IOVA on error. 100 */ 101 phys_addr_t rte_mem_virt2phy(const void *virt); 102 103 /** 104 * Get IO virtual address of any mapped virtual address in the current process. 105 * 106 * @note This function will not check internal page table. Instead, in IOVA as 107 * PA mode, it will fall back to getting real physical address (which may 108 * not match the expected IOVA, such as what was specified for external 109 * memory). 110 * 111 * @param virt 112 * The virtual address. 113 * @return 114 * The IO address or RTE_BAD_IOVA on error. 115 */ 116 rte_iova_t rte_mem_virt2iova(const void *virt); 117 118 /** 119 * Get virtual memory address corresponding to iova address. 120 * 121 * @note This function read-locks the memory hotplug subsystem, and thus cannot 122 * be used within memory-related callback functions. 123 * 124 * @param iova 125 * The iova address. 126 * @return 127 * Virtual address corresponding to iova address (or NULL if address does not 128 * exist within DPDK memory map). 129 */ 130 __rte_experimental 131 void * 132 rte_mem_iova2virt(rte_iova_t iova); 133 134 /** 135 * Get memseg to which a particular virtual address belongs. 136 * 137 * @param virt 138 * The virtual address. 139 * @param msl 140 * The memseg list in which to look up based on ``virt`` address 141 * (can be NULL). 142 * @return 143 * Memseg pointer on success, or NULL on error. 144 */ 145 __rte_experimental 146 struct rte_memseg * 147 rte_mem_virt2memseg(const void *virt, const struct rte_memseg_list *msl); 148 149 /** 150 * Get memseg list corresponding to virtual memory address. 151 * 152 * @param virt 153 * The virtual address. 154 * @return 155 * Memseg list to which this virtual address belongs to. 156 */ 157 __rte_experimental 158 struct rte_memseg_list * 159 rte_mem_virt2memseg_list(const void *virt); 160 161 /** 162 * Memseg walk function prototype. 163 * 164 * Returning 0 will continue walk 165 * Returning 1 will stop the walk 166 * Returning -1 will stop the walk and report error 167 */ 168 typedef int (*rte_memseg_walk_t)(const struct rte_memseg_list *msl, 169 const struct rte_memseg *ms, void *arg); 170 171 /** 172 * Memseg contig walk function prototype. This will trigger a callback on every 173 * VA-contiguous area starting at memseg ``ms``, so total valid VA space at each 174 * callback call will be [``ms->addr``, ``ms->addr + len``). 175 * 176 * Returning 0 will continue walk 177 * Returning 1 will stop the walk 178 * Returning -1 will stop the walk and report error 179 */ 180 typedef int (*rte_memseg_contig_walk_t)(const struct rte_memseg_list *msl, 181 const struct rte_memseg *ms, size_t len, void *arg); 182 183 /** 184 * Memseg list walk function prototype. This will trigger a callback on every 185 * allocated memseg list. 186 * 187 * Returning 0 will continue walk 188 * Returning 1 will stop the walk 189 * Returning -1 will stop the walk and report error 190 */ 191 typedef int (*rte_memseg_list_walk_t)(const struct rte_memseg_list *msl, 192 void *arg); 193 194 /** 195 * Walk list of all memsegs. 196 * 197 * @note This function read-locks the memory hotplug subsystem, and thus cannot 198 * be used within memory-related callback functions. 199 * 200 * @note This function will also walk through externally allocated segments. It 201 * is up to the user to decide whether to skip through these segments. 202 * 203 * @param func 204 * Iterator function 205 * @param arg 206 * Argument passed to iterator 207 * @return 208 * 0 if walked over the entire list 209 * 1 if stopped by the user 210 * -1 if user function reported error 211 */ 212 __rte_experimental 213 int 214 rte_memseg_walk(rte_memseg_walk_t func, void *arg); 215 216 /** 217 * Walk each VA-contiguous area. 218 * 219 * @note This function read-locks the memory hotplug subsystem, and thus cannot 220 * be used within memory-related callback functions. 221 * 222 * @note This function will also walk through externally allocated segments. It 223 * is up to the user to decide whether to skip through these segments. 224 * 225 * @param func 226 * Iterator function 227 * @param arg 228 * Argument passed to iterator 229 * @return 230 * 0 if walked over the entire list 231 * 1 if stopped by the user 232 * -1 if user function reported error 233 */ 234 __rte_experimental 235 int 236 rte_memseg_contig_walk(rte_memseg_contig_walk_t func, void *arg); 237 238 /** 239 * Walk each allocated memseg list. 240 * 241 * @note This function read-locks the memory hotplug subsystem, and thus cannot 242 * be used within memory-related callback functions. 243 * 244 * @note This function will also walk through externally allocated segments. It 245 * is up to the user to decide whether to skip through these segments. 246 * 247 * @param func 248 * Iterator function 249 * @param arg 250 * Argument passed to iterator 251 * @return 252 * 0 if walked over the entire list 253 * 1 if stopped by the user 254 * -1 if user function reported error 255 */ 256 __rte_experimental 257 int 258 rte_memseg_list_walk(rte_memseg_list_walk_t func, void *arg); 259 260 /** 261 * Walk list of all memsegs without performing any locking. 262 * 263 * @note This function does not perform any locking, and is only safe to call 264 * from within memory-related callback functions. 265 * 266 * @param func 267 * Iterator function 268 * @param arg 269 * Argument passed to iterator 270 * @return 271 * 0 if walked over the entire list 272 * 1 if stopped by the user 273 * -1 if user function reported error 274 */ 275 __rte_experimental 276 int 277 rte_memseg_walk_thread_unsafe(rte_memseg_walk_t func, void *arg); 278 279 /** 280 * Walk each VA-contiguous area without performing any locking. 281 * 282 * @note This function does not perform any locking, and is only safe to call 283 * from within memory-related callback functions. 284 * 285 * @param func 286 * Iterator function 287 * @param arg 288 * Argument passed to iterator 289 * @return 290 * 0 if walked over the entire list 291 * 1 if stopped by the user 292 * -1 if user function reported error 293 */ 294 __rte_experimental 295 int 296 rte_memseg_contig_walk_thread_unsafe(rte_memseg_contig_walk_t func, void *arg); 297 298 /** 299 * Walk each allocated memseg list without performing any locking. 300 * 301 * @note This function does not perform any locking, and is only safe to call 302 * from within memory-related callback functions. 303 * 304 * @param func 305 * Iterator function 306 * @param arg 307 * Argument passed to iterator 308 * @return 309 * 0 if walked over the entire list 310 * 1 if stopped by the user 311 * -1 if user function reported error 312 */ 313 __rte_experimental 314 int 315 rte_memseg_list_walk_thread_unsafe(rte_memseg_list_walk_t func, void *arg); 316 317 /** 318 * Return file descriptor associated with a particular memseg (if available). 319 * 320 * @note This function read-locks the memory hotplug subsystem, and thus cannot 321 * be used within memory-related callback functions. 322 * 323 * @note This returns an internal file descriptor. Performing any operations on 324 * this file descriptor is inherently dangerous, so it should be treated 325 * as read-only for all intents and purposes. 326 * 327 * @param ms 328 * A pointer to memseg for which to get file descriptor. 329 * 330 * @return 331 * Valid file descriptor in case of success. 332 * -1 in case of error, with ``rte_errno`` set to the following values: 333 * - EINVAL - ``ms`` pointer was NULL or did not point to a valid memseg 334 * - ENODEV - ``ms`` fd is not available 335 * - ENOENT - ``ms`` is an unused segment 336 * - ENOTSUP - segment fd's are not supported 337 */ 338 __rte_experimental 339 int 340 rte_memseg_get_fd(const struct rte_memseg *ms); 341 342 /** 343 * Return file descriptor associated with a particular memseg (if available). 344 * 345 * @note This function does not perform any locking, and is only safe to call 346 * from within memory-related callback functions. 347 * 348 * @note This returns an internal file descriptor. Performing any operations on 349 * this file descriptor is inherently dangerous, so it should be treated 350 * as read-only for all intents and purposes. 351 * 352 * @param ms 353 * A pointer to memseg for which to get file descriptor. 354 * 355 * @return 356 * Valid file descriptor in case of success. 357 * -1 in case of error, with ``rte_errno`` set to the following values: 358 * - EINVAL - ``ms`` pointer was NULL or did not point to a valid memseg 359 * - ENODEV - ``ms`` fd is not available 360 * - ENOENT - ``ms`` is an unused segment 361 * - ENOTSUP - segment fd's are not supported 362 */ 363 __rte_experimental 364 int 365 rte_memseg_get_fd_thread_unsafe(const struct rte_memseg *ms); 366 367 /** 368 * Get offset into segment file descriptor associated with a particular memseg 369 * (if available). 370 * 371 * @note This function read-locks the memory hotplug subsystem, and thus cannot 372 * be used within memory-related callback functions. 373 * 374 * @param ms 375 * A pointer to memseg for which to get file descriptor. 376 * @param offset 377 * A pointer to offset value where the result will be stored. 378 * 379 * @return 380 * Valid file descriptor in case of success. 381 * -1 in case of error, with ``rte_errno`` set to the following values: 382 * - EINVAL - ``ms`` pointer was NULL or did not point to a valid memseg 383 * - EINVAL - ``offset`` pointer was NULL 384 * - ENODEV - ``ms`` fd is not available 385 * - ENOENT - ``ms`` is an unused segment 386 * - ENOTSUP - segment fd's are not supported 387 */ 388 __rte_experimental 389 int 390 rte_memseg_get_fd_offset(const struct rte_memseg *ms, size_t *offset); 391 392 /** 393 * Get offset into segment file descriptor associated with a particular memseg 394 * (if available). 395 * 396 * @note This function does not perform any locking, and is only safe to call 397 * from within memory-related callback functions. 398 * 399 * @param ms 400 * A pointer to memseg for which to get file descriptor. 401 * @param offset 402 * A pointer to offset value where the result will be stored. 403 * 404 * @return 405 * Valid file descriptor in case of success. 406 * -1 in case of error, with ``rte_errno`` set to the following values: 407 * - EINVAL - ``ms`` pointer was NULL or did not point to a valid memseg 408 * - EINVAL - ``offset`` pointer was NULL 409 * - ENODEV - ``ms`` fd is not available 410 * - ENOENT - ``ms`` is an unused segment 411 * - ENOTSUP - segment fd's are not supported 412 */ 413 __rte_experimental 414 int 415 rte_memseg_get_fd_offset_thread_unsafe(const struct rte_memseg *ms, 416 size_t *offset); 417 418 /** 419 * @warning 420 * @b EXPERIMENTAL: this API may change without prior notice 421 * 422 * Register external memory chunk with DPDK. 423 * 424 * @note Using this API is mutually exclusive with ``rte_malloc`` family of 425 * API's. 426 * 427 * @note This API will not perform any DMA mapping. It is expected that user 428 * will do that themselves. 429 * 430 * @note Before accessing this memory in other processes, it needs to be 431 * attached in each of those processes by calling ``rte_extmem_attach`` in 432 * each other process. 433 * 434 * @param va_addr 435 * Start of virtual area to register. Must be aligned by ``page_sz``. 436 * @param len 437 * Length of virtual area to register. Must be aligned by ``page_sz``. 438 * @param iova_addrs 439 * Array of page IOVA addresses corresponding to each page in this memory 440 * area. Can be NULL, in which case page IOVA addresses will be set to 441 * RTE_BAD_IOVA. 442 * @param n_pages 443 * Number of elements in the iova_addrs array. Ignored if ``iova_addrs`` 444 * is NULL. 445 * @param page_sz 446 * Page size of the underlying memory 447 * 448 * @return 449 * - 0 on success 450 * - -1 in case of error, with rte_errno set to one of the following: 451 * EINVAL - one of the parameters was invalid 452 * EEXIST - memory chunk is already registered 453 * ENOSPC - no more space in internal config to store a new memory chunk 454 */ 455 __rte_experimental 456 int 457 rte_extmem_register(void *va_addr, size_t len, rte_iova_t iova_addrs[], 458 unsigned int n_pages, size_t page_sz); 459 460 /** 461 * @warning 462 * @b EXPERIMENTAL: this API may change without prior notice 463 * 464 * Unregister external memory chunk with DPDK. 465 * 466 * @note Using this API is mutually exclusive with ``rte_malloc`` family of 467 * API's. 468 * 469 * @note This API will not perform any DMA unmapping. It is expected that user 470 * will do that themselves. 471 * 472 * @note Before calling this function, all other processes must call 473 * ``rte_extmem_detach`` to detach from the memory area. 474 * 475 * @param va_addr 476 * Start of virtual area to unregister 477 * @param len 478 * Length of virtual area to unregister 479 * 480 * @return 481 * - 0 on success 482 * - -1 in case of error, with rte_errno set to one of the following: 483 * EINVAL - one of the parameters was invalid 484 * ENOENT - memory chunk was not found 485 */ 486 __rte_experimental 487 int 488 rte_extmem_unregister(void *va_addr, size_t len); 489 490 /** 491 * @warning 492 * @b EXPERIMENTAL: this API may change without prior notice 493 * 494 * Attach to external memory chunk registered in another process. 495 * 496 * @note Using this API is mutually exclusive with ``rte_malloc`` family of 497 * API's. 498 * 499 * @note This API will not perform any DMA mapping. It is expected that user 500 * will do that themselves. 501 * 502 * @param va_addr 503 * Start of virtual area to register 504 * @param len 505 * Length of virtual area to register 506 * 507 * @return 508 * - 0 on success 509 * - -1 in case of error, with rte_errno set to one of the following: 510 * EINVAL - one of the parameters was invalid 511 * ENOENT - memory chunk was not found 512 */ 513 __rte_experimental 514 int 515 rte_extmem_attach(void *va_addr, size_t len); 516 517 /** 518 * @warning 519 * @b EXPERIMENTAL: this API may change without prior notice 520 * 521 * Detach from external memory chunk registered in another process. 522 * 523 * @note Using this API is mutually exclusive with ``rte_malloc`` family of 524 * API's. 525 * 526 * @note This API will not perform any DMA unmapping. It is expected that user 527 * will do that themselves. 528 * 529 * @param va_addr 530 * Start of virtual area to unregister 531 * @param len 532 * Length of virtual area to unregister 533 * 534 * @return 535 * - 0 on success 536 * - -1 in case of error, with rte_errno set to one of the following: 537 * EINVAL - one of the parameters was invalid 538 * ENOENT - memory chunk was not found 539 */ 540 __rte_experimental 541 int 542 rte_extmem_detach(void *va_addr, size_t len); 543 544 /** 545 * Dump the physical memory layout to a file. 546 * 547 * @note This function read-locks the memory hotplug subsystem, and thus cannot 548 * be used within memory-related callback functions. 549 * 550 * @param f 551 * A pointer to a file for output 552 */ 553 void rte_dump_physmem_layout(FILE *f); 554 555 /** 556 * Get the total amount of available physical memory. 557 * 558 * @note This function read-locks the memory hotplug subsystem, and thus cannot 559 * be used within memory-related callback functions. 560 * 561 * @return 562 * The total amount of available physical memory in bytes. 563 */ 564 uint64_t rte_eal_get_physmem_size(void); 565 566 /** 567 * Get the number of memory channels. 568 * 569 * @return 570 * The number of memory channels on the system. The value is 0 if unknown 571 * or not the same on all devices. 572 */ 573 unsigned rte_memory_get_nchannel(void); 574 575 /** 576 * Get the number of memory ranks. 577 * 578 * @return 579 * The number of memory ranks on the system. The value is 0 if unknown or 580 * not the same on all devices. 581 */ 582 unsigned rte_memory_get_nrank(void); 583 584 /** 585 * @warning 586 * @b EXPERIMENTAL: this API may change without prior notice 587 * 588 * Check if all currently allocated memory segments are compliant with 589 * supplied DMA address width. 590 * 591 * @param maskbits 592 * Address width to check against. 593 */ 594 __rte_experimental 595 int rte_mem_check_dma_mask(uint8_t maskbits); 596 597 /** 598 * @warning 599 * @b EXPERIMENTAL: this API may change without prior notice 600 * 601 * Check if all currently allocated memory segments are compliant with 602 * supplied DMA address width. This function will use 603 * rte_memseg_walk_thread_unsafe instead of rte_memseg_walk implying 604 * memory_hotplug_lock will not be acquired avoiding deadlock during 605 * memory initialization. 606 * 607 * This function is just for EAL core memory internal use. Drivers should 608 * use the previous rte_mem_check_dma_mask. 609 * 610 * @param maskbits 611 * Address width to check against. 612 */ 613 __rte_experimental 614 int rte_mem_check_dma_mask_thread_unsafe(uint8_t maskbits); 615 616 /** 617 * @warning 618 * @b EXPERIMENTAL: this API may change without prior notice 619 * 620 * Set dma mask to use once memory initialization is done. Previous functions 621 * rte_mem_check_dma_mask and rte_mem_check_dma_mask_thread_unsafe can not be 622 * used safely until memory has been initialized. 623 */ 624 __rte_experimental 625 void rte_mem_set_dma_mask(uint8_t maskbits); 626 627 /** 628 * Drivers based on uio will not load unless physical 629 * addresses are obtainable. It is only possible to get 630 * physical addresses when running as a privileged user. 631 * 632 * @return 633 * 1 if the system is able to obtain physical addresses. 634 * 0 if using DMA addresses through an IOMMU. 635 */ 636 int rte_eal_using_phys_addrs(void); 637 638 639 /** 640 * Enum indicating which kind of memory event has happened. Used by callbacks to 641 * distinguish between memory allocations and deallocations. 642 */ 643 enum rte_mem_event { 644 RTE_MEM_EVENT_ALLOC = 0, /**< Allocation event. */ 645 RTE_MEM_EVENT_FREE, /**< Deallocation event. */ 646 }; 647 #define RTE_MEM_EVENT_CALLBACK_NAME_LEN 64 648 /**< maximum length of callback name */ 649 650 /** 651 * Function typedef used to register callbacks for memory events. 652 */ 653 typedef void (*rte_mem_event_callback_t)(enum rte_mem_event event_type, 654 const void *addr, size_t len, void *arg); 655 656 /** 657 * Function used to register callbacks for memory events. 658 * 659 * @note callbacks will happen while memory hotplug subsystem is write-locked, 660 * therefore some functions (e.g. `rte_memseg_walk()`) will cause a 661 * deadlock when called from within such callbacks. 662 * 663 * @note mem event callbacks not being supported is an expected error condition, 664 * so user code needs to handle this situation. In these cases, return 665 * value will be -1, and rte_errno will be set to ENOTSUP. 666 * 667 * @param name 668 * Name associated with specified callback to be added to the list. 669 * 670 * @param clb 671 * Callback function pointer. 672 * 673 * @param arg 674 * Argument to pass to the callback. 675 * 676 * @return 677 * 0 on successful callback register 678 * -1 on unsuccessful callback register, with rte_errno value indicating 679 * reason for failure. 680 */ 681 __rte_experimental 682 int 683 rte_mem_event_callback_register(const char *name, rte_mem_event_callback_t clb, 684 void *arg); 685 686 /** 687 * Function used to unregister callbacks for memory events. 688 * 689 * @param name 690 * Name associated with specified callback to be removed from the list. 691 * 692 * @param arg 693 * Argument to look for among callbacks with specified callback name. 694 * 695 * @return 696 * 0 on successful callback unregister 697 * -1 on unsuccessful callback unregister, with rte_errno value indicating 698 * reason for failure. 699 */ 700 __rte_experimental 701 int 702 rte_mem_event_callback_unregister(const char *name, void *arg); 703 704 705 #define RTE_MEM_ALLOC_VALIDATOR_NAME_LEN 64 706 /**< maximum length of alloc validator name */ 707 /** 708 * Function typedef used to register memory allocation validation callbacks. 709 * 710 * Returning 0 will allow allocation attempt to continue. Returning -1 will 711 * prevent allocation from succeeding. 712 */ 713 typedef int (*rte_mem_alloc_validator_t)(int socket_id, 714 size_t cur_limit, size_t new_len); 715 716 /** 717 * @brief Register validator callback for memory allocations. 718 * 719 * Callbacks registered by this function will be called right before memory 720 * allocator is about to trigger allocation of more pages from the system if 721 * said allocation will bring total memory usage above specified limit on 722 * specified socket. User will be able to cancel pending allocation if callback 723 * returns -1. 724 * 725 * @note callbacks will happen while memory hotplug subsystem is write-locked, 726 * therefore some functions (e.g. `rte_memseg_walk()`) will cause a 727 * deadlock when called from within such callbacks. 728 * 729 * @note validator callbacks not being supported is an expected error condition, 730 * so user code needs to handle this situation. In these cases, return 731 * value will be -1, and rte_errno will be set to ENOTSUP. 732 * 733 * @param name 734 * Name associated with specified callback to be added to the list. 735 * 736 * @param clb 737 * Callback function pointer. 738 * 739 * @param socket_id 740 * Socket ID on which to watch for allocations. 741 * 742 * @param limit 743 * Limit above which to trigger callbacks. 744 * 745 * @return 746 * 0 on successful callback register 747 * -1 on unsuccessful callback register, with rte_errno value indicating 748 * reason for failure. 749 */ 750 __rte_experimental 751 int 752 rte_mem_alloc_validator_register(const char *name, 753 rte_mem_alloc_validator_t clb, int socket_id, size_t limit); 754 755 /** 756 * @brief Unregister validator callback for memory allocations. 757 * 758 * @param name 759 * Name associated with specified callback to be removed from the list. 760 * 761 * @param socket_id 762 * Socket ID on which to watch for allocations. 763 * 764 * @return 765 * 0 on successful callback unregister 766 * -1 on unsuccessful callback unregister, with rte_errno value indicating 767 * reason for failure. 768 */ 769 __rte_experimental 770 int 771 rte_mem_alloc_validator_unregister(const char *name, int socket_id); 772 773 #ifdef __cplusplus 774 } 775 #endif 776 777 #endif /* _RTE_MEMORY_H_ */ 778