doc: add Meson coding style to contributors guide
[dpdk.git] / lib / librte_eal / include / rte_memory.h
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_ */