Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'bpf: add support for BTF_KIND_DECL_TAG typedef'

Yonghong Song says:

====================

Latest upstream llvm-project added support for btf_decl_tag attributes
for typedef declarations ([1], [2]). Similar to other btf_decl_tag cases,
func/func_param/global_var/struct/union/field, btf_decl_tag with typedef
declaration can carry information from kernel source to clang compiler
and then to dwarf/BTF, for bpf verification or other use cases.

This patch set added kernel support for BTF_KIND_DECL_TAG to typedef
declaration (Patch 1). Additional selftests are added to cover
unit testing, dedup, or bpf program usage of btf_decl_tag with typedef.
(Patches 2, 3 and 4). The btf documentation is updated to include
BTF_KIND_DECL_TAG typedef (Patch 5).

[1] https://reviews.llvm.org/D110127
[2] https://reviews.llvm.org/D112259
====================

Signed-off-by: Alexei Starovoitov <ast@kernel.org>

+89 -13
+3 -3
Documentation/bpf/btf.rst
··· 474 474 * ``info.kind_flag``: 0 475 475 * ``info.kind``: BTF_KIND_DECL_TAG 476 476 * ``info.vlen``: 0 477 - * ``type``: ``struct``, ``union``, ``func`` or ``var`` 477 + * ``type``: ``struct``, ``union``, ``func``, ``var`` or ``typedef`` 478 478 479 479 ``btf_type`` is followed by ``struct btf_decl_tag``.:: 480 480 ··· 483 483 }; 484 484 485 485 The ``name_off`` encodes btf_decl_tag attribute string. 486 - The ``type`` should be ``struct``, ``union``, ``func`` or ``var``. 487 - For ``var`` type, ``btf_decl_tag.component_idx`` must be ``-1``. 486 + The ``type`` should be ``struct``, ``union``, ``func``, ``var`` or ``typedef``. 487 + For ``var`` or ``typedef`` type, ``btf_decl_tag.component_idx`` must be ``-1``. 488 488 For the other three types, if the btf_decl_tag attribute is 489 489 applied to the ``struct``, ``union`` or ``func`` itself, 490 490 ``btf_decl_tag.component_idx`` must be ``-1``. Otherwise,
+2 -2
kernel/bpf/btf.c
··· 468 468 static bool btf_type_is_decl_tag_target(const struct btf_type *t) 469 469 { 470 470 return btf_type_is_func(t) || btf_type_is_struct(t) || 471 - btf_type_is_var(t); 471 + btf_type_is_var(t) || btf_type_is_typedef(t); 472 472 } 473 473 474 474 u32 btf_nr_types(const struct btf *btf) ··· 3885 3885 3886 3886 component_idx = btf_type_decl_tag(t)->component_idx; 3887 3887 if (component_idx != -1) { 3888 - if (btf_type_is_var(next_type)) { 3888 + if (btf_type_is_var(next_type) || btf_type_is_typedef(next_type)) { 3889 3889 btf_verifier_log_type(env, v->t, "Invalid component_idx"); 3890 3890 return -EINVAL; 3891 3891 }
+77 -6
tools/testing/selftests/bpf/prog_tests/btf.c
··· 3903 3903 .btf_load_err = true, 3904 3904 .err_str = "Invalid component_idx", 3905 3905 }, 3906 + { 3907 + .descr = "decl_tag test #13, typedef, well-formed", 3908 + .raw_types = { 3909 + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3910 + BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [2] */ 3911 + BTF_DECL_TAG_ENC(NAME_TBD, 2, -1), 3912 + BTF_END_RAW, 3913 + }, 3914 + BTF_STR_SEC("\0t\0tag"), 3915 + .map_type = BPF_MAP_TYPE_ARRAY, 3916 + .map_name = "tag_type_check_btf", 3917 + .key_size = sizeof(int), 3918 + .value_size = 4, 3919 + .key_type_id = 1, 3920 + .value_type_id = 1, 3921 + .max_entries = 1, 3922 + }, 3923 + { 3924 + .descr = "decl_tag test #14, typedef, invalid component_idx", 3925 + .raw_types = { 3926 + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 3927 + BTF_TYPEDEF_ENC(NAME_TBD, 1), /* [2] */ 3928 + BTF_DECL_TAG_ENC(NAME_TBD, 2, 0), 3929 + BTF_END_RAW, 3930 + }, 3931 + BTF_STR_SEC("\0local\0tag"), 3932 + .map_type = BPF_MAP_TYPE_ARRAY, 3933 + .map_name = "tag_type_check_btf", 3934 + .key_size = sizeof(int), 3935 + .value_size = 4, 3936 + .key_type_id = 1, 3937 + .value_type_id = 1, 3938 + .max_entries = 1, 3939 + .btf_load_err = true, 3940 + .err_str = "Invalid component_idx", 3941 + }, 3906 3942 3907 3943 }; /* struct btf_raw_test raw_tests[] */ 3908 3944 ··· 6877 6841 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8), 6878 6842 BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */ 6879 6843 BTF_TYPE_FLOAT_ENC(NAME_TBD, 2), /* [14] float */ 6880 - BTF_DECL_TAG_ENC(NAME_TBD, 13, -1), /* [15] tag */ 6881 - BTF_DECL_TAG_ENC(NAME_TBD, 13, 1), /* [16] tag */ 6844 + BTF_DECL_TAG_ENC(NAME_TBD, 13, -1), /* [15] decl_tag */ 6845 + BTF_DECL_TAG_ENC(NAME_TBD, 13, 1), /* [16] decl_tag */ 6846 + BTF_DECL_TAG_ENC(NAME_TBD, 7, -1), /* [17] decl_tag */ 6882 6847 BTF_END_RAW, 6883 6848 }, 6884 - BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P"), 6849 + BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P\0Q"), 6885 6850 }, 6886 6851 .expect = { 6887 6852 .raw_types = { ··· 6906 6869 BTF_FUNC_PROTO_ARG_ENC(NAME_TBD, 8), 6907 6870 BTF_FUNC_ENC(NAME_TBD, 12), /* [13] func */ 6908 6871 BTF_TYPE_FLOAT_ENC(NAME_TBD, 2), /* [14] float */ 6909 - BTF_DECL_TAG_ENC(NAME_TBD, 13, -1), /* [15] tag */ 6910 - BTF_DECL_TAG_ENC(NAME_TBD, 13, 1), /* [16] tag */ 6872 + BTF_DECL_TAG_ENC(NAME_TBD, 13, -1), /* [15] decl_tag */ 6873 + BTF_DECL_TAG_ENC(NAME_TBD, 13, 1), /* [16] decl_tag */ 6874 + BTF_DECL_TAG_ENC(NAME_TBD, 7, -1), /* [17] decl_tag */ 6911 6875 BTF_END_RAW, 6912 6876 }, 6913 - BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P"), 6877 + BTF_STR_SEC("\0A\0B\0C\0D\0E\0F\0G\0H\0I\0J\0K\0L\0M\0N\0O\0P\0Q"), 6914 6878 }, 6915 6879 .opts = { 6916 6880 .dont_resolve_fwds = false, ··· 7201 7163 BTF_END_RAW, 7202 7164 }, 7203 7165 BTF_STR_SEC("\0t\0m1\0m2\0tag1\0tag2\0tag3"), 7166 + }, 7167 + .opts = { 7168 + .dont_resolve_fwds = false, 7169 + }, 7170 + }, 7171 + { 7172 + .descr = "dedup: typedef tags", 7173 + .input = { 7174 + .raw_types = { 7175 + /* int */ 7176 + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 7177 + BTF_TYPEDEF_ENC(NAME_NTH(1), 1), /* [2] */ 7178 + BTF_TYPEDEF_ENC(NAME_NTH(1), 1), /* [3] */ 7179 + /* tag -> t: tag1, tag2 */ 7180 + BTF_DECL_TAG_ENC(NAME_NTH(2), 2, -1), /* [4] */ 7181 + BTF_DECL_TAG_ENC(NAME_NTH(3), 2, -1), /* [5] */ 7182 + /* tag -> t: tag1, tag3 */ 7183 + BTF_DECL_TAG_ENC(NAME_NTH(2), 3, -1), /* [6] */ 7184 + BTF_DECL_TAG_ENC(NAME_NTH(4), 3, -1), /* [7] */ 7185 + BTF_END_RAW, 7186 + }, 7187 + BTF_STR_SEC("\0t\0tag1\0tag2\0tag3"), 7188 + }, 7189 + .expect = { 7190 + .raw_types = { 7191 + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 7192 + BTF_TYPEDEF_ENC(NAME_NTH(1), 1), /* [2] */ 7193 + BTF_DECL_TAG_ENC(NAME_NTH(2), 2, -1), /* [3] */ 7194 + BTF_DECL_TAG_ENC(NAME_NTH(3), 2, -1), /* [4] */ 7195 + BTF_DECL_TAG_ENC(NAME_NTH(4), 2, -1), /* [5] */ 7196 + BTF_END_RAW, 7197 + }, 7198 + BTF_STR_SEC("\0t\0tag1\0tag2\0tag3"), 7204 7199 }, 7205 7200 .opts = { 7206 7201 .dont_resolve_fwds = false,
+7 -2
tools/testing/selftests/bpf/progs/tag.c
··· 24 24 int c; 25 25 } __tag1 __tag2; 26 26 27 + typedef struct { 28 + int a; 29 + int b; 30 + } value_t __tag1 __tag2; 31 + 27 32 struct { 28 33 __uint(type, BPF_MAP_TYPE_HASH); 29 34 __uint(max_entries, 3); 30 35 __type(key, struct key_t); 31 - __type(value, __u64); 36 + __type(value, value_t); 32 37 } hashmap1 SEC(".maps"); 33 38 34 39 35 40 static __noinline int foo(int x __tag1 __tag2) __tag1 __tag2 36 41 { 37 42 struct key_t key; 38 - __u64 val = 1; 43 + value_t val = {}; 39 44 40 45 key.a = key.b = key.c = x; 41 46 bpf_map_update_elem(&hashmap1, &key, &val, 0);