Re: Notification when an eBPF map is modified

Jesper Dangaard Brouer

On Sat, 17 Feb 2018 13:49:22 +0000 Teng Qin via iovisor-dev <iovisor-dev@...> wrote:

We were looking for a mechanism transparent to the eBPF program, though.
A possible rational is to have an hot-standby copy of the program
(including the state) in some other location, but I don't want my
dataplane to be aware of that.


You could also (use another BPF program or ftrace) to trace the
bpf_map_update_elem Tracepoint. But in that case you get all update calls
and would need to filter for the one you are interested on your own:)
That is a good idea.

Try it out via perf-record to see if it contains what you need:

$ perf record -e bpf:bpf_map_update_elem -a

$ perf script
xdp_redirect_ma 2273 [011] 261187.968223: bpf:bpf_map_update_elem: map type= ufd=4 key=[00 00 00 00] val=[07 00 00 00]

Looking at the above output and tracepoint kernel code, we should
extend that with a map_id to easily identify/filter what map you are
interested in.

See patch below signature (not even compile tested).

Example for attaching to tracepoints see:

Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat

tracepoint: add map id to bpf tracepoints

From: Jesper Dangaard Brouer <brouer@...>

include/trace/events/bpf.h | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/trace/events/bpf.h b/include/trace/events/bpf.h
index 150185647e6b..e6479ba45261 100644
--- a/include/trace/events/bpf.h
+++ b/include/trace/events/bpf.h
@@ -140,7 +140,7 @@ TRACE_EVENT(bpf_map_create,
__entry->flags = map->map_flags;
__entry->ufd = ufd;
+// TODO also add map_id here
TP_printk("map type=%s ufd=%d key=%u val=%u max=%u flags=%x",
__print_symbolic(__entry->type, __MAP_TYPE_SYM_TAB),
__entry->ufd, __entry->size_key, __entry->size_value,
@@ -199,15 +199,18 @@ DECLARE_EVENT_CLASS(bpf_obj_map,
__field(u32, type)
__field(int, ufd)
__string(path, pname->name)
+ __field(u32, map_id)

__assign_str(path, pname->name);
__entry->type = map->map_type;
__entry->ufd = ufd;
+ __entry->map_id = map->id;

- TP_printk("map type=%s ufd=%d path=%s",
+ TP_printk("map id=%u type=%s ufd=%d path=%s",
+ __entry->map_id,
__print_symbolic(__entry->type, __MAP_TYPE_SYM_TAB),
__entry->ufd, __get_str(path))
@@ -244,6 +247,7 @@ DECLARE_EVENT_CLASS(bpf_map_keyval,
__dynamic_array(u8, val, map->value_size)
__field(bool, val_trunc)
__field(int, ufd)
+ __field(u32, map_id)

@@ -255,9 +259,11 @@ DECLARE_EVENT_CLASS(bpf_map_keyval,
__entry->val_len = min(map->value_size, 16U);
__entry->val_trunc = map->value_size != __entry->val_len;
__entry->ufd = ufd;
+ __entry->map_id = map->id;

- TP_printk("map type=%s ufd=%d key=[%s%s] val=[%s%s]",
+ TP_printk("map id=%d type=%s ufd=%d key=[%s%s] val=[%s%s]",
+ __entry->map_id,
__print_symbolic(__entry->type, __MAP_TYPE_SYM_TAB),
__print_hex(__get_dynamic_array(key), __entry->key_len),

Join to automatically receive all group messages.