rte_memory.h(3)
πΈ rte_memory.h β Library Functions Manual π
okay bestie, gather round, because we're about to get into the memory of DPDK and honestly? it's giving main character energy π§β¨
β¨ NAME β¨
rte_memory.h β the memory-related RTE API, no cap π
π SYNOPSIS π
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <rte_bitops.h>
#include <rte_common.h>
#include <rte_config.h>
#include <rte_eal_memconfig.h>
#include <rte_fbarray.h>
π¦ Data Structures
struct rte_memsegstruct rte_memseg_list
π Macros
#define SOCKET_ID_ANY -1
#define RTE_MEMSEG_FLAG_DO_NOT_FREE RTE_BIT32(0)
#define RTE_MEMSEG_FLAG_DIRTY RTE_BIT32(1)
#define RTE_MEM_EVENT_CALLBACK_NAME_LEN 64
#define RTE_MEM_ALLOC_VALIDATOR_NAME_LEN 64
π Typedefs
typedef int(* rte_memseg_walk_t) (const struct rte_memseg_list *msl,
const struct rte_memseg *ms, void *arg)
typedef int(* rte_memseg_contig_walk_t) (const struct rte_memseg_list
*msl, const struct rte_memseg *ms, size_t len, void *arg)
typedef int(* rte_memseg_list_walk_t) (const struct rte_memseg_list
*msl, void *arg)
typedef void(* rte_mem_event_callback_t) (enum rte_mem_event event_type,
const void *addr, size_t len, void *arg)
typedef int(* rte_mem_alloc_validator_t) (int socket_id, size_t
cur_limit, size_t new_len)
π Enumerations
enum rte_mem_event { RTE_MEM_EVENT_ALLOC = 0, RTE_MEM_EVENT_FREE }
β Functions
int rte_mem_lock_page (const void *virt)
phys_addr_t rte_mem_virt2phy (const void *virt)
rte_iova_t rte_mem_virt2iova (const void *virt)
void * rte_mem_iova2virt (rte_iova_t iova)
struct rte_memseg * rte_mem_virt2memseg (const void *virt, const struct
rte_memseg_list *msl)
struct rte_memseg_list * rte_mem_virt2memseg_list (const void *virt)
int rte_memseg_walk (rte_memseg_walk_t func, void *arg)
int rte_memseg_contig_walk (rte_memseg_contig_walk_t func, void *arg)
int rte_memseg_list_walk (rte_memseg_list_walk_t func, void *arg)
__rte_locks_excluded(rte_mcfg_mem_get_lock())
int rte_memseg_walk_thread_unsafe (rte_memseg_walk_t func, void *arg)
int rte_memseg_contig_walk_thread_unsafe (rte_memseg_contig_walk_t func,
void *arg)
int rte_memseg_list_walk_thread_unsafe (rte_memseg_list_walk_t func,
void *arg)
int rte_memseg_get_fd (const struct rte_memseg *ms)
int rte_memseg_get_fd_thread_unsafe (const struct rte_memseg *ms)
int rte_memseg_get_fd_offset (const struct rte_memseg *ms, size_t
*offset)
int rte_memseg_get_fd_offset_thread_unsafe (const struct rte_memseg *ms,
size_t *offset)
int rte_extmem_register (void *va_addr, size_t len, rte_iova_t
iova_addrs[], unsigned int n_pages, size_t page_sz)
int rte_extmem_unregister (void *va_addr, size_t len)
int rte_extmem_attach (void *va_addr, size_t len)
int rte_extmem_detach (void *va_addr, size_t len)
void rte_dump_physmem_layout (FILE *f)
uint64_t rte_eal_get_physmem_size (void)
unsigned rte_memory_get_nchannel (void)
unsigned rte_memory_get_nrank (void)
int rte_mem_check_dma_mask (uint8_t maskbits)
int rte_mem_check_dma_mask_thread_unsafe (uint8_t maskbits)
void rte_mem_set_dma_mask (uint8_t maskbits)
int rte_eal_using_phys_addrs (void)
int rte_mem_event_callback_register (const char *name,
rte_mem_event_callback_t clb, void *arg)
int rte_mem_event_callback_unregister (const char *name, void *arg)
int rte_mem_alloc_validator_register (const char *name,
rte_mem_alloc_validator_t clb, int socket_id, size_t limit)
Register validator callback for memory allocations.
int rte_mem_alloc_validator_unregister (const char *name, int socket_id)
Unregister validator callback for memory allocations.
__rte_experimental void rte_memzero_explicit (void *dst, size_t sz)
static __rte_experimental bool rte_memeq_timingsafe (const void *a,
const void *b, size_t n)
π₯ Detailed Description π₯
Memory-related RTE API. that's the whole vibe, she's the memory plug π
Definition in file rte_memory.h.
π Macro Definition Documentation π
#define SOCKET_ID_ANY -1
Any NUMA socket. like, any of them bestie, she doesn't discriminate π«Ά
Definition at line 39 of file rte_memory.h.
#define RTE_MEMSEG_FLAG_DO_NOT_FREE RTE_BIT32(0)
Prevent this segment from being freed back to the OS. she's holding on and she is NOT letting go π€
Definition at line 42 of file rte_memory.h.
#define RTE_MEMSEG_FLAG_DIRTY RTE_BIT32(1)
This segment is not filled with zeros. it's messy, it's unbothered, it's dirty π
Definition at line 44 of file rte_memory.h.
#define RTE_MEM_EVENT_CALLBACK_NAME_LEN 64
maximum length of callback name β 64, periodt.
Definition at line 609 of file rte_memory.h.
#define RTE_MEM_ALLOC_VALIDATOR_NAME_LEN 64
maximum length of alloc validator name β also 64, consistency queen π
Definition at line 665 of file rte_memory.h.
π¦ Typedef Documentation π¦
typedef int(* rte_memseg_walk_t) (const struct rte_memseg_list *msl, const struct rte_memseg *ms, void *arg)
Memseg walk function prototype. a lil function you hand over so the walker knows what to do at every stop β¨
- Returning 0 will continue walk
- Returning 1 will stop the walk
- Returning -1 will stop the walk and report error
Definition at line 167 of file rte_memory.h.
typedef int(* rte_memseg_contig_walk_t) (const struct rte_memseg_list *msl, const struct rte_memseg *ms, size_t len, void *arg)
Memseg contig walk function prototype. This will trigger a callback on every VA-contiguous area starting at memseg ms, so total valid VA space at each callback call will be [ms->addr, ms->addr + len). contiguous and cute πΈ
- Returning 0 will continue walk
- Returning 1 will stop the walk
- Returning -1 will stop the walk and report error
Definition at line 179 of file rte_memory.h.
typedef int(* rte_memseg_list_walk_t) (const struct rte_memseg_list *msl, void *arg)
Memseg list walk function prototype. This will trigger a callback on every allocated memseg list. she's thorough, she does not skip π
- Returning 0 will continue walk
- Returning 1 will stop the walk
- Returning -1 will stop the walk and report error
Definition at line 190 of file rte_memory.h.
typedef void(* rte_mem_event_callback_t) (enum rte_mem_event event_type, const void *addr, size_t len, void *arg)
Function typedef used to register callbacks for memory events. you're basically subscribing to the memory drama channel π£
Definition at line 615 of file rte_memory.h.
typedef int(* rte_mem_alloc_validator_t) (int socket_id, size_t cur_limit, size_t new_len)
Function typedef used to register memory allocation validation callbacks. she's the bouncer at the allocation club π
- Returning 0 will allow allocation attempt to continue.
- Returning -1 will prevent allocation from succeeding.
Definition at line 673 of file rte_memory.h.
π Enumeration Type Documentation π
enum rte_mem_event
Enum indicating which kind of memory event has happened. Used by callbacks to distinguish between memory allocations and deallocations. two moods, one enum π
Enumerator
RTE_MEM_EVENT_ALLOCβ Allocation event.RTE_MEM_EVENT_FREEβ Deallocation event.
Definition at line 605 of file rte_memory.h.
π Function Documentation π
int rte_mem_lock_page (const void * virt)
Lock page in physical memory and prevent from swapping. she's staying put, no swap, no escape π
Parameters
virtβ The virtual address.
Returns
0 on success, negative on error.
phys_addr_t rte_mem_virt2phy (const void * virt)
Get physical address of any mapped virtual address in the current process. It is found by browsing the /proc/self/pagemap special file. The page must be locked. yes, must. don't come for her without locking first π
Parameters
virtβ The virtual address.
Returns
The physical address or RTE_BAD_IOVA on error.
rte_iova_t rte_mem_virt2iova (const void * virt)
Get IO virtual address of any mapped virtual address in the current process.
Note β This function will not check internal page table. Instead, in IOVA as PA mode, it will fall back to getting real physical address (which may not match the expected IOVA, such as what was specified for external memory). so like... read the note bestie, don't be surprised π
Parameters
virtβ The virtual address.
Returns
The IO address or RTE_BAD_IOVA on error.
void * rte_mem_iova2virt (rte_iova_t iova)
Get virtual memory address corresponding to iova address. the reverse uno card π
Note β This function read-locks the memory hotplug subsystem, and thus cannot be used within memory-related callback functions. deadlock vibes, we don't do that here π
Parameters
iovaβ The iova address.
Returns
Virtual address corresponding to iova address (or NULL if address does not exist within DPDK memory map).
struct rte_memseg * rte_mem_virt2memseg (const void * virt, const struct rte_memseg_list * msl)
Get memseg to which a particular virtual address belongs. find your people, find your memseg π«Ά
Parameters
virtβ The virtual address.mslβ The memseg list in which to look up based on virt address (can be NULL).
Returns
Memseg pointer on success, or NULL on error.
struct rte_memseg_list * rte_mem_virt2memseg_list (const void * virt)
Get memseg list corresponding to virtual memory address. the group chat this address is in π¬
Parameters
virtβ The virtual address.
Returns
Memseg list to which this virtual address belongs to.
int rte_memseg_walk (rte_memseg_walk_t func, void * arg)
Walk list of all memsegs. she's doing a lap around the whole block πΆβοΈβ¨
Note β This function read-locks the memory hotplug subsystem, and thus cannot be used within memory-related callback functions.
Note β This function will also walk through externally allocated segments. It is up to the user to decide whether to skip through these segments. so like, if you don't wanna see the externals, that's on you to filter, bestie π
Parameters
funcβ Iterator functionargβ Argument passed to iterator
Returns
0 if walked over the entire list 1 if stopped by the user -1 if user function reported error
int rte_memseg_contig_walk (rte_memseg_contig_walk_t func, void * arg)
Walk each VA-contiguous area. one contiguous stretch at a time, she's neat like that πΈ
Note β This function read-locks the memory hotplug subsystem, and thus cannot be used within memory-related callback functions.
Note β This function will also walk through externally allocated segments. It is up to the user to decide whether to skip through these segments.
Parameters
funcβ Iterator functionargβ Argument passed to iterator
Returns
0 if walked over the entire list 1 if stopped by the user -1 if user function reported error
int rte_memseg_list_walk (rte_memseg_list_walk_t func, void * arg)
Walk each allocated memseg list. every single one, no skips π
Note β This function read-locks the memory hotplug subsystem, and thus cannot be used within memory-related callback functions.
Note β This function will also walk through externally allocated segments. It is up to the user to decide whether to skip through these segments.
Parameters
funcβ Iterator functionargβ Argument passed to iterator
Returns
0 if walked over the entire list 1 if stopped by the user -1 if user function reported error
int rte_memseg_walk_thread_unsafe (rte_memseg_walk_t func, void * arg)
Walk list of all memsegs without performing any locking. she's off the leash, she's feral, she's thread unsafe π
Note β This function does not perform any locking, and is only safe to call from within memory-related callback functions. ONLY from within those. the way that this will absolutely ruin your day otherwise π
Parameters
funcβ Iterator functionargβ Argument passed to iterator
Returns β 0 if it walked over the entire list, 1 if the user stopped it, and -1 if your user function reported an error. that's the whole vibe check, bestie π
int rte_memseg_contig_walk_thread_unsafe (rte_memseg_contig_walk_t func, void * arg)
walk every VA-contiguous area, and do it without touching any locks. yes ma'am, raw and unfiltered π
Note: this one does NOT do any locking, so it is only safe to call from inside memory-related callback functions. anywhere else and you're in danger girlie π
Parameters
funcβ the iterator function, aka the little guy doing the walking πΆββοΈargβ the argument that gets passed to the iterator
Returns β 0 if it walked the whole list, 1 if the user stopped it, -1 if the user function reported an error β¨
int rte_memseg_list_walk_thread_unsafe (rte_memseg_list_walk_t func, void * arg)
walk every allocated memseg list, still no locking whatsoever. living dangerously, we love that for you π¦
Note: no locking happens here either, so it's only safe to call from inside memory-related callback functions. no cap π«Ά
Parameters
funcβ the iterator functionargβ argument passed to the iterator
Returns β 0 if it walked the entire list, 1 if stopped by the user, -1 if the user function reported an error β
int rte_memseg_get_fd (const struct rte_memseg * ms)
hand you the file descriptor tied to a particular memseg, if one exists. conditional queen π
Note: this function read-locks the memory hotplug subsystem, which means you cannot call it from inside memory-related callback functions. deadlock central, so no π alsoooo what it hands back is an internal file descriptor. doing literally any operations on it is inherently dangerous, so treat it as read-only for all intents and purposes, periodt.
Parameters
msβ a pointer to the memseg you want the file descriptor for.
Returns β a valid file descriptor on success. On error it's -1, with rte_errno set to one of these:
EINVALβ themspointer wasNULLor didn't point to a valid memsegENODEVβ themsfd is not availableENOENTβmsis an unused segmentENOTSUPβ segment fd's are not supported
int rte_memseg_get_fd_thread_unsafe (const struct rte_memseg * ms)
same energy as before β file descriptor for a particular memseg, if it's available π
Note: this one performs no locking, so it's only safe to call from inside memory-related callback functions. iykyk π§ and again, this returns an internal file descriptor, and operating on it is inherently dangerous β treat it as read-only for all intents and purposes.
Parameters
msβ a pointer to the memseg you want the file descriptor for.
Returns β valid file descriptor on success, -1 on error with rte_errno set to:
EINVALβmspointer wasNULLor did not point to a valid memsegENODEVβmsfd is not availableENOENTβmsis an unused segmentENOTSUPβ segment fd's are not supported
int rte_memseg_get_fd_offset (const struct rte_memseg * ms, size_t * offset)
get the offset into the segment file descriptor for a particular memseg, if that fd is even available πΈ
Note: read-locks the memory hotplug subsystem, so no calling this from memory-related callback functions. we are NOT doing that today π«
Parameters
msβ a pointer to the memseg for which to get the file descriptor.offsetβ a pointer to the offset value where the result will be stored.
Returns β valid file descriptor on success. On error, -1, with rte_errno set to one of these:
EINVALβmspointer wasNULLor did not point to a valid memsegEINVALβoffsetpointer wasNULLENODEVβmsfd is not availableENOENTβmsis an unused segmentENOTSUPβ segment fd's are not supported
yes there are two different EINVAL situations up there, that's not a typo, that's canon π
int rte_memseg_get_fd_offset_thread_unsafe (const struct rte_memseg * ms, size_t * offset)
the lockless twin: offset into the segment file descriptor for a particular memseg, if available π¦
Note: no locking here, so it's only safe to call from within memory-related callback functions.
Parameters
msβ a pointer to the memseg for which to get the file descriptor.offsetβ a pointer to the offset value where the result will be stored.
Returns β valid file descriptor on success, -1 on error, with rte_errno set to one of:
EINVALβmspointer wasNULLor did not point to a valid memsegEINVALβoffsetpointer wasNULLENODEVβmsfd is not availableENOENTβmsis an unused segmentENOTSUPβ segment fd's are not supported
int rte_extmem_register (void * va_addr, size_t len, rte_iova_t iova_addrs[], unsigned int n_pages, size_t page_sz)
register an external memory chunk with DPDK. main character energy β¨
Note: using this API is mutually exclusive with therte_mallocfamily of API's. pick a lane bestie π this API will not perform any DMA mapping β it's expected that the user does that themselves. you're on your own for that part π«Ά before accessing this memory in other processes, it needs to be attached in each of those processes by callingrte_extmem_attachin each other process. every single one. no skipping.
Parameters
va_addrβ start of the virtual area to register. must be aligned bypage_sz.lenβ length of the virtual area to register. must be aligned bypage_sz.iova_addrsβ array of page IOVA addresses corresponding to each page in this memory area. can beNULL, in which case page IOVA addresses will be set toRTE_BAD_IOVA.n_pagesβ number of elements in theiova_addrsarray. ignored ifiova_addrsisNULL.page_szβ page size of the underlying memory.
Returns
0on success π-1on error, withrte_errnoset to one of these:EINVALβ one of the parameters was invalidEEXISTβ memory chunk is already registeredENOSPCβ no more space in internal config to store a new memory chunk
int rte_extmem_unregister (void * va_addr, size_t len)
unregister an external memory chunk from DPDK. it's giving goodbye π
Note: using this API is mutually exclusive with therte_mallocfamily of API's. this API will not perform any DMA unmapping β the user is expected to do that themselves. before calling this function, all other processes must callrte_extmem_detachto detach from the memory area. all of them. don't leave anybody hanging π€
Parameters
va_addrβ start of the virtual area to unregisterlenβ length of the virtual area to unregister
Returns
0on success-1on error, withrte_errnoset to one of these:EINVALβ one of the parameters was invalidENOENTβ memory chunk was not found
int rte_extmem_attach (void * va_addr, size_t len)
attach to an external memory chunk that was registered in another process. the way that it pulls up on someone else's memory π₯
Note: using this API is mutually exclusive with the rte_malloc family of API's. this API will not perform any DMA mapping β expected that the user does that themselves.
Parameters
va_addrβ start of the virtual area to registerlenβ length of the virtual area to register
Returns
0on success-1on error, withrte_errnoset to one of these:EINVALβ one of the parameters was invalidENOENTβ memory chunk was not found
int rte_extmem_detach (void * va_addr, size_t len)
detach from an external memory chunk registered in another process. boundaries, we love to see them π
Note: using this API is mutually exclusive with the rte_malloc family of API's. this API will not perform any DMA unmapping β the user is expected to do that themselves.
Parameters
va_addrβ start of the virtual area to unregisterlenβ length of the virtual area to unregister
Returns
0on success-1on error, withrte_errnoset to one of these:EINVALβ one of the parameters was invalidENOENTβ memory chunk was not found
void rte_dump_physmem_layout (FILE * f)
dump the physical memory layout out to a file. a little memory receipt, if you will π§Ύβ¨
Note: read-locks the memory hotplug subsystem, so it cannot be used within memory-related callback functions.
Parameters
fβ a pointer to a file for output.
uint64_t rte_eal_get_physmem_size (void )
get the total amount of available physical memory. the full plate, no crumbs π
Note: read-locks the memory hotplug subsystem, so nope, not from inside memory-related callback functions.
Returns β the total amount of available physical memory, in bytes. every single byte accounted for π
unsigned rte_memory_get_nchannel (void )
get the number of memory channels π
Returns β the number of memory channels on the system. the value is 0 if it's unknown or if it's not the same on all devices. shrug emoji, honestly π€·ββοΈ
unsigned rte_memory_get_nrank (void )
get the number of memory ranks π
Returns β the number of memory ranks on the system. the value is 0 if unknown or not the same on all devices.
int rte_mem_check_dma_mask (uint8_t maskbits)
check whether all currently allocated memory segments are compliant with the supplied DMA address width. doing a little compliance audit, bestie π
Parameters
maskbitsβ address width to check against.
int rte_mem_check_dma_mask_thread_unsafe (uint8_t maskbits)
check whether all currently allocated memory segments are compliant with the supplied DMA address width β but the thread-unsafe way. this one uses rte_memseg_walk_thread_unsafe instead of rte_memseg_walk, implying that memory_hotplug_lock will not be acquired, which avoids a deadlock during memory initialization π crisis averted.
this function is just for EAL core memory internal use. drivers should be using the previous rte_mem_check_dma_mask. stay in your lane, drivers π
Parameters
maskbitsβ address width to check against.
void rte_mem_set_dma_mask (uint8_t maskbits)
set the dma mask to use once memory initialization is done. the previous functions rte_mem_check_dma_mask and rte_mem_check_dma_mask_thread_unsafe cannot be used safely until memory has been initialized. so, like, wait your turn β³
int rte_eal_using_phys_addrs (void )
drivers based on uio will not load unless physical addresses are obtainable. and physical addresses are only obtainable when you're running as a privileged user. so like, privileges check, babes π
Returns β 1 if the system is able to obtain physical addresses. 0 if it's using DMA addresses through an IOMMU.
int rte_mem_event_callback_register (const char * name, rte_mem_event_callback_t clb, void * arg)
the function you use to register callbacks for memory events. setting up your little notifications, iconic β¨
Note: callbacks will happen while the memory hotplug subsystem is write-locked, which means some functions (like, for example,rte_memseg_walk()) will cause a deadlock when you call them from inside such callbacks. so don't π mem event callbacks not being supported is an expected error condition, so your user code needs to handle that situation. in these cases, the return value will be-1, andrte_errnowill be set toENOTSUP.
Parameters
nameβ the name that's tagging along with the callback you're adding to the list.clbβ the callback function pointer, aka the actual function that gets run.argβ the argument that gets passed to the callback.
Returns
0 when the callback registers successfully, -1 when it doesn't β and then rte_errno is holding the reason it flopped.
π rte_mem_event_callback_unregister()
int rte_mem_event_callback_unregister (const char * name, void * arg)
The function you call when you need to unregister callbacks for memory events. It's giving mutual breakup, but make it memory events π«Ά
Parameters
nameβ the name tied to the callback you want removed from the list.argβ the argument to look for among the callbacks that go by that callback name.
Returns
0 on a successful callback unregister, -1 when it does not go through β with rte_errno telling you why it failed.
π rte_mem_alloc_validator_register()
int rte_mem_alloc_validator_register (const char * name,
rte_mem_alloc_validator_t clb, int socket_id, size_t limit)
Okay so this one registers a validator callback for memory allocations β¨ Callbacks you register here get called right before the memory allocator is about to trigger an allocation of more pages from the system β but only if that allocation would push total memory usage above the limit you specified, on the socket you specified. And if your callback returns -1, you get to cancel the pending allocation. Veto power, iconic π
Note β these callbacks happen while the memory hotplug subsystem is write-locked, so certain functions (like rte_memseg_walk(), for example) will cause a deadlock when you call them from inside one of these callbacks. Don't do that, bestie π
Also note β validator callbacks not being supported is an expected error condition, so your user code genuinely has to handle it. In those cases the return value will be-1, andrte_errnowill be set toENOTSUP.
Parameters
nameβ the name associated with the callback being added to the list.clbβ the callback function pointer.socket_idβ the socket ID you want to watch for allocations on.limitβ the limit above which the callbacks get triggered.
Returns
0 on successful callback register, -1 on unsuccessful callback register, with rte_errno indicating the reason for the failure.
π« rte_mem_alloc_validator_unregister()
int rte_mem_alloc_validator_unregister (const char * name, int socket_id)
Unregisters a validator callback for memory allocations. Same breakup arc, different callback π
Parameters
nameβ the name associated with the callback being removed from the list.socket_idβ the socket ID you're watching for allocations on.
Returns
0 on a successful callback unregister, -1 on an unsuccessful callback unregister, with rte_errno indicating the reason for failure.
π§Ό rte_memzero_explicit()
__rte_experimental void rte_memzero_explicit (void * dst, size_t sz)
Warning β EXPERIMENTAL: this API may change without prior notice. So don't get too attached π
Fills memory with zero's (hi, sensitive keys π). Normally using memset() is completely fine, but when you need to clear out local data before it goes out of scope, use rte_memzero_explicit() instead β that's how you stop the compiler from optimizing the zeroing operation away. The compiler thought it was being clever. It was not π
Parameters
dstβ the target buffer.szβ the number of bytes to fill.
β±οΈ rte_memeq_timingsafe()
__rte_experimental bool rte_memeq_timingsafe (const void * a, const void *
b, size_t n) [inline], [static]
Warning β EXPERIMENTAL: this API may change without prior notice. Yes, again π₯
Timing-safe memory equality comparison. The way that this function compares two memory regions in constant timeβ¦ it's resistant to timing side-channel attacks, periodt. The execution time depends only on the length parameter β never on the actual data values being compared. Snitching is simply not on the menu π
This matters especially for cryptographic operations, where timing differences could leak information about secret keys, passwords, or any other sensitive data. No leaking the lore, bestie π
Parameters
aβ pointer to the first memory region to compare.bβ pointer to the second memory region to compare.nβ the number of bytes to compare.
Returns
true if the memory regions are identical, false if they differ.
Definition at line 775 of file rte_memory.h.
π Author
Generated automatically by Doxygen for DPDK from the source code. Not a human, not a girlie, just a documentation generator doing its little thing π¦
And that's a wrap on rte_memory.h(3), bestie β brought to you by DPDK, Version 25.11.3, straight from the source code, no cap. Go forth and manage your memory responsibly, you absolute icon πβ¨
π¦ where this page comes from
- ubuntu resolute: dpdk-doc 25.11.3-0ubuntu0.26.04.1 Β· BSD-3-Clause
- ubuntu stonking: dpdk-doc 25.11.3-1 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms