Reputation: 77
In my understanding, when userspace use bpf_map_update_elem(int fd, void *key, void *value, __u64 flags)
,
first, userspace find the map through the fd
;
second, userspace make a memory in user-space;
and ....
I know a little bit, but the specific process is still unclear.
So I wanna know what the detail is when userspace run API map helpers.
Upvotes: 2
Views: 929
Reputation: 9114
Because you mention “user space”, I am unsure what you are talking about exactly. So let's start with some clarification.
BPF maps (or at least, most of the existing types, including hash maps and arrays) can be accessed in two ways:
From user space, there is no “helper” function. Interaction with maps is entirely (*) done through the bpf()
syscall (with the BPF_MAP_LOOKUP_ELEM
, BPF_MAP_UPDATE_ELEM
, BPF_MAP_DELETE_ELEM
commands passed to the syscall as its first argument). See the bpf(2)
manual page for more details. This is what you use in a user space application that would load and manage BPF programs and maps, say bpftool
for example.
From kernel space, i.e. from a BPF program, things work differently and access is done with one of the BPF “helpers” such as bpf_map_update_elem(struct bpf_map *map, const void *key, const void *value, u64 flags)
. See the bpf-helpers(7)
man page for details on existing helpers. You can find details on those helper calls in the Cilium guide, or obviously by reading kernel code (e.g. for array maps). They look like low-level C function calls, with BPF registers being used to pass the necessary arguments, and then it calls from the BPF program instructions into the helper that is compiled as part of the kernel binary.
So you mentioned bpf_map_update_elem()
and user space. Although this is the name for the helper on the kernel side, I suspect you might be talking about the function with the same name which is offered by the libbpf library, to provide a wrapper around the bpf()
system call. So what happens with this function is rather simple.
bpf()
system call and used by the kernel as a reference to the map.key
and value
should already have been filled at this point, and they are passed to the kernel through the bpf()
syscall to tell what entry to update, and with what value. Same things for the flags.bpf()
has been called, what happens on the kernel side is rather straightforwards. Mostly, the kernel check permissions, validates the arguments (to make sure they are safe and consistent with the map), then it updates the actual data. For array maps, array_map_update_elem()
(used with the BPF helper on kernel side too, see link above) is called eventually.(*) Some interactions might actually be done without the bpf()
system call, I believe that with “global data” stored in BPF maps, use applications mmap()
to the kernel memory. But this goes beyond the scope of basic usage of arrays and maps.
Upvotes: 4