BTF is required for 'struct bpf_timer' to be recognized inside map value. The bpf timers are supported inside inner maps. Remember 'struct btf *' in inner_map_meta to make it available to the verifier in the sequence: struct bpf_map *inner_map = bpf_map_lookup_elem(&outer_map, ...); if (inner_map) timer = bpf_map_lookup_elem(&inner_map, ...);
Unified · Split
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 3 | */ | 3 | */ |
| 4 | #include <linux/slab.h> | 4 | #include <linux/slab.h> |
| 5 | #include <linux/bpf.h> | 5 | #include <linux/bpf.h> |
| 6 | #include <linux/btf.h> | ||
| 6 | 7 | ||
| 7 | #include "map_in_map.h" | 8 | #include "map_in_map.h" |
| 8 | 9 | ||
| @@ -51,6 +52,10 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd) · 42 unmodified lines | |||
| 51 | inner_map_meta->max_entries = inner_map->max_entries; | 52 | inner_map_meta->max_entries = inner_map->max_entries; |
| 52 | inner_map_meta->spin_lock_off = inner_map->spin_lock_off; | 53 | inner_map_meta->spin_lock_off = inner_map->spin_lock_off; |
| 53 | inner_map_meta->timer_off = inner_map->timer_off; | 54 | inner_map_meta->timer_off = inner_map->timer_off; |
| 55 | if (inner_map->btf) { | ||
| 56 | btf_get(inner_map->btf); | ||
| 57 | inner_map_meta->btf = inner_map->btf; | ||
| 58 | } | ||
| 54 | 59 | ||
| 55 | /* Misc members not needed in bpf_map_meta_equal() check. */ | 60 | /* Misc members not needed in bpf_map_meta_equal() check. */ |
| 56 | inner_map_meta->ops = inner_map->ops; | 61 | inner_map_meta->ops = inner_map->ops; |
| @@ -66,6 +71,7 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd) · 9 unmodified lines | |||
| 66 | 71 | ||
| 67 | void bpf_map_meta_free(struct bpf_map *map_meta) | 72 | void bpf_map_meta_free(struct bpf_map *map_meta) |
| 68 | { | 73 | { |
| 74 | btf_put(map_meta->btf); | ||
| 69 | kfree(map_meta); | 75 | kfree(map_meta); |
| 70 | } | 76 | } |
| 71 | 77 | ||