Re: Notification when an eBPF map is modified

Yonghong Song

On Mon, Aug 6, 2018 at 11:53 AM, Raffaele Sommese <raffysommy@...> wrote:
Il giorno lun 6 ago 2018 alle ore 19:40 Y Song <ys114321@...> ha scritto:

On Mon, Aug 6, 2018 at 10:17 AM, Raffaele Sommese <raffysommy@...> wrote:
bpf tracepoints have been removed from recent linux so the you need to
use kprobe to trace update/delete.

typical map_update_elem and map_delete_elem first argument is
'struct bpf_map *map', you can get name and id from there:
Hello again :)
It seems that there is 2 function that can be traced inside the
kernel, one is map_update_elem, and it is the syscall, the other one
is the BPF helper.
I have successful attach my ebpf code to the first one, but it doesn't
have as parameter struct bpf_map *map (it have a union bpf_attr).
If I attach my program to the bpf_map_update_elem (that I think is the
function name of BPF helper), I don't receive any event.
I'm using the last version of bcc and of kernel.
I try also with kprobe program of perf kernel suite with the same results.
I was looking for this helper BPF_CALL_4 (bpf_map_update_elem, struct
bpf_map *, map, void *, key, void *, value, u64, flags)
Please directly use the map lookup function for the specific map.
For example, for hashmap, the verifier is smart enough to
change the byte code to call the underlying hashmap map lookup function.
Thank you, right now I will try only to implement a solution for hashmap.
I have detected a strange behavior for lookup I can receive the event
when the map was looked, but for the updates, I don't receive
I have checked the kernel and there was the map_gen_lookup.
The strange thing is that if I use kprobe tool I can see the event on
Here is my test code: (I have tried with lookup and it works)
Okay, the htab_map_update_elem is indeed called, but you cannot trace it.
The following kernel code in kernel/bpf/syscall.c explained the reason:

/* must increment bpf_prog_active to avoid kprobe+bpf triggering from
* inside bpf map update or delete otherwise deadlocks are possible
if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH) {
err = bpf_percpu_hash_update(map, key, value, attr->flags);
} else if (map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY) {
err = bpf_percpu_array_update(map, key, value, attr->flags);
} else if (IS_FD_ARRAY(map)) {
err = bpf_fd_array_map_update_elem(map, f.file, key, value,
} else if (map->map_type == BPF_MAP_TYPE_HASH_OF_MAPS) {
err = bpf_fd_htab_map_update_elem(map, f.file, key, value,
} else {
err = map->ops->map_update_elem(map, key, value, attr->flags);

The bpf_prog_active will prevent later kprobe for htab_map_update_elem.

How can we solve this problem then? One possible solution is as follows:
. disassemble vmlinux to find a proper place in function "map_update_elem"
where you can get the "map" (struct bpf_map *map) in a register, e.g.,
the insn offset inside map_update_elem is OFFSET and this OFFSET
should be outside the above preempt/__this_cpu_{inc/dec} region.
. improve to trace function+offset. the possible format could be 'map_update_elem+OFFSET ...'
The attach_kprobe API should already support function_name + offset format.

Thanks again,

Raffaele Sommese
About me:
Gpg Key:
GPG key ID: 0x830b1428cf91db2a on

Join to automatically receive all group messages.