History

Merge branch 'libbpf: Support uniform BTF-defined key/value specification across all BPF maps'

Hengqi Chen says: ==================== Currently a bunch of (usually pretty specialized) BPF maps do not support specifying BTF types for they key and value. For such maps, specifying their definition like this: struct { __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); __type(key, int); __type(value, int); } my_perf_buf SEC(".maps"); Would actually produce warnings about retrying BPF map creation without BTF. Users are forced to know such nuances and use __uint(key_size, 4) instead. This is non-uniform, annoying, and inconvenient. This patch set teaches libbpf to recognize those specialized maps and removes BTF type IDs when creating BPF map. Also, update existing BPF selftests to exericse this change. ====================

Andrii Nakryiko committed 5 years ago

Commit d636c8d2 parents 7bceeb9 bd368cb14 files · +62 −40Browse files

Unified · Split

14 files
  1. tools/lib/bpf/libbpf.c +24 −0
  2. tools/testing/selftests/bpf/progs/kfree_skb.c +2 −2
  3. tools/testing/selftests/bpf/progs/perf_event_stackmap.c +2 −2
  4. tools/testing/selftests/bpf/progs/sockmap_verdict_prog.c +6 −6
  5. tools/testing/selftests/bpf/progs/test_btf_map_in_map.c +7 −7
  6. tools/testing/selftests/bpf/progs/test_map_in_map.c +4 −6
  7. tools/testing/selftests/bpf/progs/test_map_in_map_invalid.c +1 −1
  8. tools/testing/selftests/bpf/progs/test_pe_preserve_elems.c +4 −4
  9. tools/testing/selftests/bpf/progs/test_perf_buffer.c +2 −2
  10. tools/testing/selftests/bpf/progs/test_select_reuseport_kern.c +2 −2
  11. tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c +2 −2
  12. tools/testing/selftests/bpf/progs/test_stacktrace_map.c +2 −2
  13. tools/testing/selftests/bpf/progs/test_tcpnotify_kern.c +2 −2
  14. tools/testing/selftests/bpf/progs/test_xdp_bpf2bpf.c +2 −2
tools/lib/bpf/libbpf.c+24−0
@@ -4669,6 +4669,30 @@ static int bpf_object__create_map(struct bpf_object *obj, struct bpf_map *map, b · 4668 unmodified lines
4669 create_attr.inner_map_fd = map->inner_map_fd;4669 create_attr.inner_map_fd = map->inner_map_fd;
4670 }4670 }
4671 4671
4672 switch (def->type) {
4673 case BPF_MAP_TYPE_PERF_EVENT_ARRAY:
4674 case BPF_MAP_TYPE_CGROUP_ARRAY:
4675 case BPF_MAP_TYPE_STACK_TRACE:
4676 case BPF_MAP_TYPE_ARRAY_OF_MAPS:
4677 case BPF_MAP_TYPE_HASH_OF_MAPS:
4678 case BPF_MAP_TYPE_DEVMAP:
4679 case BPF_MAP_TYPE_DEVMAP_HASH:
4680 case BPF_MAP_TYPE_CPUMAP:
4681 case BPF_MAP_TYPE_XSKMAP:
4682 case BPF_MAP_TYPE_SOCKMAP:
4683 case BPF_MAP_TYPE_SOCKHASH:
4684 case BPF_MAP_TYPE_QUEUE:
4685 case BPF_MAP_TYPE_STACK:
4686 case BPF_MAP_TYPE_RINGBUF:
4687 create_attr.btf_fd = 0;
4688 create_attr.btf_key_type_id = 0;
4689 create_attr.btf_value_type_id = 0;
4690 map->btf_key_type_id = 0;
4691 map->btf_value_type_id = 0;
4692 default:
4693 break;
4694 }
4695
4672 if (obj->gen_loader) {4696 if (obj->gen_loader) {
4673 bpf_gen__map_create(obj->gen_loader, &create_attr, is_inner ? -1 : map - obj->maps);4697 bpf_gen__map_create(obj->gen_loader, &create_attr, is_inner ? -1 : map - obj->maps);
4674 /* Pretend to have valid FD to pass various fd >= 0 checks.4698 /* Pretend to have valid FD to pass various fd >= 0 checks.
tools/testing/selftests/bpf/progs/kfree_skb.c+2−2
@@ -9,8 +9,8 @@ · 8 unmodified lines
9char _license[] SEC("license") = "GPL";9char _license[] SEC("license") = "GPL";
10struct {10struct {
11 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);11 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
12 __uint(key_size, sizeof(int));12 __type(key, int);
13 __uint(value_size, sizeof(int));13 __type(value, int);
14} perf_buf_map SEC(".maps");14} perf_buf_map SEC(".maps");
15 15
16#define _(P) (__builtin_preserve_access_index(P))16#define _(P) (__builtin_preserve_access_index(P))
tools/testing/selftests/bpf/progs/perf_event_stackmap.c+2−2
@@ -11,8 +11,8 @@ typedef __u64 stack_trace_t[PERF_MAX_STACK_DEPTH]; · 10 unmodified lines
11struct {11struct {
12 __uint(type, BPF_MAP_TYPE_STACK_TRACE);12 __uint(type, BPF_MAP_TYPE_STACK_TRACE);
13 __uint(max_entries, 16384);13 __uint(max_entries, 16384);
14 __uint(key_size, sizeof(__u32));14 __type(key, __u32);
15 __uint(value_size, sizeof(stack_trace_t));15 __type(value, stack_trace_t);
16} stackmap SEC(".maps");16} stackmap SEC(".maps");
17 17
18struct {18struct {
tools/testing/selftests/bpf/progs/sockmap_verdict_prog.c+6−6
@@ -7,22 +7,22 @@ int _version SEC("version") = 1; · 6 unmodified lines
7struct {7struct {
8 __uint(type, BPF_MAP_TYPE_SOCKMAP);8 __uint(type, BPF_MAP_TYPE_SOCKMAP);
9 __uint(max_entries, 20);9 __uint(max_entries, 20);
10 __uint(key_size, sizeof(int));10 __type(key, int);
11 __uint(value_size, sizeof(int));11 __type(value, int);
12} sock_map_rx SEC(".maps");12} sock_map_rx SEC(".maps");
13 13
14struct {14struct {
15 __uint(type, BPF_MAP_TYPE_SOCKMAP);15 __uint(type, BPF_MAP_TYPE_SOCKMAP);
16 __uint(max_entries, 20);16 __uint(max_entries, 20);
17 __uint(key_size, sizeof(int));17 __type(key, int);
18 __uint(value_size, sizeof(int));18 __type(value, int);
19} sock_map_tx SEC(".maps");19} sock_map_tx SEC(".maps");
20 20
21struct {21struct {
22 __uint(type, BPF_MAP_TYPE_SOCKMAP);22 __uint(type, BPF_MAP_TYPE_SOCKMAP);
23 __uint(max_entries, 20);23 __uint(max_entries, 20);
24 __uint(key_size, sizeof(int));24 __type(key, int);
25 __uint(value_size, sizeof(int));25 __type(value, int);
26} sock_map_msg SEC(".maps");26} sock_map_msg SEC(".maps");
27 27
28struct {28struct {
tools/testing/selftests/bpf/progs/test_btf_map_in_map.c+7−7
@@ -21,8 +21,8 @@ struct inner_map_sz2 { · 20 unmodified lines
21struct outer_arr {21struct outer_arr {
22 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);22 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
23 __uint(max_entries, 3);23 __uint(max_entries, 3);
24 __uint(key_size, sizeof(int));24 __type(key, int);
25 __uint(value_size, sizeof(int));25 __type(value, int);
26 /* it's possible to use anonymous struct as inner map definition here */26 /* it's possible to use anonymous struct as inner map definition here */
27 __array(values, struct {27 __array(values, struct {
28 __uint(type, BPF_MAP_TYPE_ARRAY);28 __uint(type, BPF_MAP_TYPE_ARRAY);
@@ -61,8 +61,8 @@ struct inner_map_sz4 { · 32 unmodified lines
61struct outer_arr_dyn {61struct outer_arr_dyn {
62 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);62 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
63 __uint(max_entries, 3);63 __uint(max_entries, 3);
64 __uint(key_size, sizeof(int));64 __type(key, int);
65 __uint(value_size, sizeof(int));65 __type(value, int);
66 __array(values, struct {66 __array(values, struct {
67 __uint(type, BPF_MAP_TYPE_ARRAY);67 __uint(type, BPF_MAP_TYPE_ARRAY);
68 __uint(map_flags, BPF_F_INNER_MAP);68 __uint(map_flags, BPF_F_INNER_MAP);
@@ -81,7 +81,7 @@ struct outer_arr_dyn { · 12 unmodified lines
81struct outer_hash {81struct outer_hash {
82 __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);82 __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
83 __uint(max_entries, 5);83 __uint(max_entries, 5);
84 __uint(key_size, sizeof(int));84 __type(key, int);
85 /* Here everything works flawlessly due to reuse of struct inner_map85 /* Here everything works flawlessly due to reuse of struct inner_map
86 * and compiler will complain at the attempt to use non-inner_map86 * and compiler will complain at the attempt to use non-inner_map
87 * references below. This is great experience.87 * references below. This is great experience.
@@ -111,8 +111,8 @@ struct sockarr_sz2 { · 23 unmodified lines
111struct outer_sockarr_sz1 {111struct outer_sockarr_sz1 {
112 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);112 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
113 __uint(max_entries, 1);113 __uint(max_entries, 1);
114 __uint(key_size, sizeof(int));114 __type(key, int);
115 __uint(value_size, sizeof(int));115 __type(value, int);
116 __array(values, struct sockarr_sz1);116 __array(values, struct sockarr_sz1);
117} outer_sockarr SEC(".maps") = {117} outer_sockarr SEC(".maps") = {
118 .values = { (void *)&sockarr_sz1 },118 .values = { (void *)&sockarr_sz1 },
tools/testing/selftests/bpf/progs/test_map_in_map.c+4−6
@@ -9,18 +9,16 @@ struct { · 8 unmodified lines
9 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);9 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
10 __uint(max_entries, 1);10 __uint(max_entries, 1);
11 __uint(map_flags, 0);11 __uint(map_flags, 0);
12 __uint(key_size, sizeof(__u32));12 __type(key, __u32);
13 /* must be sizeof(__u32) for map in map */13 __type(value, __u32);
14 __uint(value_size, sizeof(__u32));
15} mim_array SEC(".maps");14} mim_array SEC(".maps");
16 15
17struct {16struct {
18 __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);17 __uint(type, BPF_MAP_TYPE_HASH_OF_MAPS);
19 __uint(max_entries, 1);18 __uint(max_entries, 1);
20 __uint(map_flags, 0);19 __uint(map_flags, 0);
21 __uint(key_size, sizeof(int));20 __type(key, int);
22 /* must be sizeof(__u32) for map in map */21 __type(value, __u32);
23 __uint(value_size, sizeof(__u32));
24} mim_hash SEC(".maps");22} mim_hash SEC(".maps");
25 23
26SEC("xdp")24SEC("xdp")
tools/testing/selftests/bpf/progs/test_map_in_map_invalid.c+1−1
@@ -13,7 +13,7 @@ struct inner { · 12 unmodified lines
13struct {13struct {
14 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);14 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
15 __uint(max_entries, 0); /* This will make map creation to fail */15 __uint(max_entries, 0); /* This will make map creation to fail */
16 __uint(key_size, sizeof(__u32));16 __type(key, __u32);
17 __array(values, struct inner);17 __array(values, struct inner);
18} mim SEC(".maps");18} mim SEC(".maps");
19 19
tools/testing/selftests/bpf/progs/test_pe_preserve_elems.c+4−4
@@ -7,15 +7,15 @@ · 6 unmodified lines
7struct {7struct {
8 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);8 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
9 __uint(max_entries, 1);9 __uint(max_entries, 1);
10 __uint(key_size, sizeof(int));10 __type(key, int);
11 __uint(value_size, sizeof(int));11 __type(value, int);
12} array_1 SEC(".maps");12} array_1 SEC(".maps");
13 13
14struct {14struct {
15 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);15 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
16 __uint(max_entries, 1);16 __uint(max_entries, 1);
17 __uint(key_size, sizeof(int));17 __type(key, int);
18 __uint(value_size, sizeof(int));18 __type(value, int);
19 __uint(map_flags, BPF_F_PRESERVE_ELEMS);19 __uint(map_flags, BPF_F_PRESERVE_ELEMS);
20} array_2 SEC(".maps");20} array_2 SEC(".maps");
21 21
tools/testing/selftests/bpf/progs/test_perf_buffer.c+2−2
@@ -8,8 +8,8 @@ · 7 unmodified lines
8 8
9struct {9struct {
10 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);10 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
11 __uint(key_size, sizeof(int));11 __type(key, int);
12 __uint(value_size, sizeof(int));12 __type(value, int);
13} perf_buf_map SEC(".maps");13} perf_buf_map SEC(".maps");
14 14
15SEC("tp/raw_syscalls/sys_enter")15SEC("tp/raw_syscalls/sys_enter")
tools/testing/selftests/bpf/progs/test_select_reuseport_kern.c+2−2
@@ -24,8 +24,8 @@ int _version SEC("version") = 1; · 23 unmodified lines
24struct {24struct {
25 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);25 __uint(type, BPF_MAP_TYPE_ARRAY_OF_MAPS);
26 __uint(max_entries, 1);26 __uint(max_entries, 1);
27 __uint(key_size, sizeof(__u32));27 __type(key, __u32);
28 __uint(value_size, sizeof(__u32));28 __type(value, __u32);
29} outer_map SEC(".maps");29} outer_map SEC(".maps");
30 30
31struct {31struct {
tools/testing/selftests/bpf/progs/test_stacktrace_build_id.c+2−2
@@ -28,8 +28,8 @@ struct { · 27 unmodified lines
28 __uint(type, BPF_MAP_TYPE_STACK_TRACE);28 __uint(type, BPF_MAP_TYPE_STACK_TRACE);
29 __uint(max_entries, 128);29 __uint(max_entries, 128);
30 __uint(map_flags, BPF_F_STACK_BUILD_ID);30 __uint(map_flags, BPF_F_STACK_BUILD_ID);
31 __uint(key_size, sizeof(__u32));31 __type(key, __u32);
32 __uint(value_size, sizeof(stack_trace_t));32 __type(value, stack_trace_t);
33} stackmap SEC(".maps");33} stackmap SEC(".maps");
34 34
35struct {35struct {
tools/testing/selftests/bpf/progs/test_stacktrace_map.c+2−2
@@ -27,8 +27,8 @@ typedef __u64 stack_trace_t[PERF_MAX_STACK_DEPTH]; · 26 unmodified lines
27struct {27struct {
28 __uint(type, BPF_MAP_TYPE_STACK_TRACE);28 __uint(type, BPF_MAP_TYPE_STACK_TRACE);
29 __uint(max_entries, 16384);29 __uint(max_entries, 16384);
30 __uint(key_size, sizeof(__u32));30 __type(key, __u32);
31 __uint(value_size, sizeof(stack_trace_t));31 __type(value, stack_trace_t);
32} stackmap SEC(".maps");32} stackmap SEC(".maps");
33 33
34struct {34struct {
tools/testing/selftests/bpf/progs/test_tcpnotify_kern.c+2−2
@@ -24,8 +24,8 @@ struct { · 23 unmodified lines
24struct {24struct {
25 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);25 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
26 __uint(max_entries, 2);26 __uint(max_entries, 2);
27 __uint(key_size, sizeof(int));27 __type(key, int);
28 __uint(value_size, sizeof(__u32));28 __type(value, __u32);
29} perf_event_map SEC(".maps");29} perf_event_map SEC(".maps");
30 30
31int _version SEC("version") = 1;31int _version SEC("version") = 1;
tools/testing/selftests/bpf/progs/test_xdp_bpf2bpf.c+2−2
@@ -36,8 +36,8 @@ struct meta { · 35 unmodified lines
36 36
37struct {37struct {
38 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);38 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
39 __uint(key_size, sizeof(int));39 __type(key, int);
40 __uint(value_size, sizeof(int));40 __type(value, int);
41} perf_buf_map SEC(".maps");41} perf_buf_map SEC(".maps");
42 42
43__u64 test_result_fentry = 0;43__u64 test_result_fentry = 0;