When looking at the source code for BCC and the Linux kernel to identify how BPF
map lookups worked I learned something – the BPF lookup and update functions
de-reference the pointers you pass it as key and value, and then memcpy
the
data.
After rummaging around the source code, you can see that it does the following:
- Create a kernel data structure
kmalloc
’d to be the size of the key data type - Copies the data stored in
key
’s memory location into thekmalloc
’d region byte-by-byte from user space to kernel space - Creates a hash using all the data stored in the
kmalloc
’d key - Looks up the value stored in the BPF map using that hashed key
- Copies all the data in the BPF map into a similarly
kmalloc
’d value buffer - Copies the data from kernel space back to user space
This means a few things –
-
You need to pass a reference to the data you want to store, if that data is on the stack, it will
memcpy
the data at that location into the hash, and then back when you do a lookup. -
If you have complex structures that you want to store, you will want to keep them on the heap and pass a pointer to the structure - this means that the key will have a consistent memory address stored inside of it; so that you avoid copying lots of data to and from kernel space, otherwise it will get expensive.