Map type BPF_MAP_TYPE_ARRAY
The array map type is a generic map type with no restrictions on the structure of the value. Like a normal array, the array map has a numeric key starting at 0 and incrementing.
Attributes
While the value_size
is essentially unrestricted, the key_size
must always be 4
indicating the key is a 32-bit unsigned integer.
The value of value_size
shouldn't exceed KMALLOC_MAX_SIZE
. KMALLOC_MAX_SIZE
is the maximum size which can be allocated by the kernel memory allocator, its exact value being dependant on a number of factors. If this edge case is hit a -E2BIG
error number is returned to the map create syscall.
Syscall commands
The following syscall commands work with this map type:
Helper functions
The following helper functions work with this map type:
Flags
The following flags are supported by this map type.
BPF_F_NUMA_NODE
When set, the numa_node
attribute is respected during map creation.
BPF_F_MMAPABLE
Setting this flag on a BPF_MAP_TYPE_ARRAY
will allow userspace programs to mmap the array values into the userspace process, effectively making a shared memory region between eBPF programs and a userspace program.
This can significantly improve read and write performance since there is no syscall overhead to access the map.
There are a few limitation however:
- Maps containing spin locks can't be memory mapped. A map can be created with this flag but any
mmap
call will result in a-ENOTSUPP
error code. - Maps containing timers can't be memory mapped. A map can be created with this flag but any
mmap
call will result in a-ENOTSUPP
error code. - Maps which have been frozen can't be memory mapped. The
mmap
call will result in a-EPERM
error code. - Maps with the
BPF_F_RDONLY_PROG
flag set cannot be memory mapped, themmap
call would result in a-EACCES
error code.
BPF_F_RDONLY
Setting this flag will make it so the map can only be read via the syscall interface, but not written to.
For details please check the generic description.
BPF_F_WRONLY
Setting this flag will make it so the map can only be written to via the syscall interface, but not read from.
BPF_F_RDONLY_PROG
Setting this flag will make it so the map can only be read via helper functions, but not written to.
For details please check the generic description.
BPF_F_WRONLY_PROG
Setting this flag will make it so the map can only be written to via helper functions, but not read from.
For details please check the generic description.
BPF_F_INNER_MAP
Global data
In regular C programs running in userspace it is not uncommon to use global variables. These live in the heap memory accessible by the processes, the memory location of which are relocated by the operating system when the program is started.
In eBPF we have no heap, only the stack and pointers into kernel space. To work around the issue, we use array maps. The compiler will place global data into the .data
, .rodata
, and .bss
ELF sections. The loader will take these sections and turn them into array maps with a single key (max_entries
set to 1) and its value the same size as the binary blob in the ELF section.
The compiler emits special LDIMM64
instructions with the first source register set to BPF_PSEUDO_MAP_VALUE
and an offset into the map value. The loader will relocate the correct map file descriptor into it as well. For details, check out the instruction set page.
All of this results in the ability to get a pointer into the global data in a single instruction much like in regular userspace programs.