diff mbox series

[bpf-next,v2,13/18] selftests/bpf: Test new enum kflag and enum64 API functions

Message ID 20220514031329.3245856-1-yhs@fb.com (mailing list archive)
State Superseded
Delegated to: BPF
Headers show
Series bpf: Add 64bit enum value support | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR fail PR summary
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count fail Series longer than 15 patches (and no cover letter)
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/cc_maintainers warning 7 maintainers not CCed: netdev@vger.kernel.org kafai@fb.com john.fastabend@gmail.com shuah@kernel.org kpsingh@kernel.org linux-kselftest@vger.kernel.org songliubraving@fb.com
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 0 this patch: 0
netdev/checkpatch warning WARNING: line length of 83 exceeds 80 columns WARNING: line length of 94 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-1 fail Logs for Kernel LATEST on ubuntu-latest with gcc
bpf/vmtest-bpf-next-VM_Test-2 fail Logs for Kernel LATEST on ubuntu-latest with llvm-15
bpf/vmtest-bpf-next-VM_Test-3 fail Logs for Kernel LATEST on z15 with gcc

Commit Message

Yonghong Song May 14, 2022, 3:13 a.m. UTC
Add tests to use the new enum kflag and enum64 API functions
in selftest btf_write.

Signed-off-by: Yonghong Song <yhs@fb.com>
---
 tools/testing/selftests/bpf/btf_helpers.c     |  21 +++-
 .../selftests/bpf/prog_tests/btf_write.c      | 114 +++++++++++++-----
 2 files changed, 105 insertions(+), 30 deletions(-)

Comments

Andrii Nakryiko May 17, 2022, 11:40 p.m. UTC | #1
On Fri, May 13, 2022 at 8:13 PM Yonghong Song <yhs@fb.com> wrote:
>
> Add tests to use the new enum kflag and enum64 API functions
> in selftest btf_write.
>
> Signed-off-by: Yonghong Song <yhs@fb.com>
> ---
>  tools/testing/selftests/bpf/btf_helpers.c     |  21 +++-
>  .../selftests/bpf/prog_tests/btf_write.c      | 114 +++++++++++++-----
>  2 files changed, 105 insertions(+), 30 deletions(-)

[...]

> @@ -307,6 +308,48 @@ static void gen_btf(struct btf *btf)
>         ASSERT_EQ(t->type, 1, "tag_type");
>         ASSERT_STREQ(btf_type_raw_dump(btf, 20),
>                      "[20] TYPE_TAG 'tag1' type_id=1", "raw_dump");
> +
> +       /* ENUM64 */
> +       id = btf__add_enum64(btf, "e1", 8, true);
> +       ASSERT_EQ(id, 21, "enum64_id");
> +       err = btf__add_enum64_value(btf, "v1", -1);
> +       ASSERT_OK(err, "v1_res");
> +       err = btf__add_enum64_value(btf, "v2", 0x123456789); /* 4886718345 */
> +       ASSERT_OK(err, "v2_res");
> +       t = btf__type_by_id(btf, 21);
> +       ASSERT_STREQ(btf__str_by_offset(btf, t->name_off), "e1", "enum64_name");
> +       ASSERT_EQ(btf_kind(t), BTF_KIND_ENUM64, "enum64_kind");
> +       ASSERT_EQ(btf_vlen(t), 2, "enum64_vlen");
> +       ASSERT_EQ(t->size, 8, "enum64_sz");
> +       v64 = btf_enum64(t) + 0;
> +       ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v1", "v1_name");
> +       ASSERT_EQ(v64->val_hi32, 0xffffffff, "v1_val");
> +       ASSERT_EQ(v64->val_lo32, 0xffffffff, "v1_val");
> +       v64 = btf_enum64(t) + 1;
> +       ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v2", "v2_name");
> +       ASSERT_EQ(v64->val_hi32, 0x1, "v2_val");
> +       ASSERT_EQ(v64->val_lo32, 0x23456789, "v2_val");
> +       ASSERT_STREQ(btf_type_raw_dump(btf, 21),
> +                    "[21] ENUM64 'e1' size=8 vlen=2\n"

we should emit and validate kflag for enum/enum64. Or maybe
"encoding=SIGNED|UNSIGNED" to match INT's output, not sure which one
is best, but we probably want to make sure that kflag is reflected in
bpftool and selftests output, right?

> +                    "\t'v1' val=-1\n"
> +                    "\t'v2' val=4886718345", "raw_dump");
> +
> +       id = btf__add_enum64(btf, "e1", 8, false);
> +       ASSERT_EQ(id, 22, "enum64_id");
> +       err = btf__add_enum64_value(btf, "v1", 0xffffffffFFFFFFFF); /* 18446744073709551615 */
> +       ASSERT_OK(err, "v1_res");
> +       t = btf__type_by_id(btf, 22);
> +       ASSERT_STREQ(btf__str_by_offset(btf, t->name_off), "e1", "enum64_name");
> +       ASSERT_EQ(btf_kind(t), BTF_KIND_ENUM64, "enum64_kind");
> +       ASSERT_EQ(btf_vlen(t), 1, "enum64_vlen");
> +       ASSERT_EQ(t->size, 8, "enum64_sz");
> +       v64 = btf_enum64(t) + 0;
> +       ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v1", "v1_name");
> +       ASSERT_EQ(v64->val_hi32, 0xffffffff, "v1_val");
> +       ASSERT_EQ(v64->val_lo32, 0xffffffff, "v1_val");
> +       ASSERT_STREQ(btf_type_raw_dump(btf, 22),
> +                    "[22] ENUM64 'e1' size=8 vlen=1\n"
> +                    "\t'v1' val=18446744073709551615", "raw_dump");
>  }
>
>  static void test_btf_add()

[...]
Yonghong Song May 18, 2022, 9:12 p.m. UTC | #2
On 5/17/22 4:40 PM, Andrii Nakryiko wrote:
> On Fri, May 13, 2022 at 8:13 PM Yonghong Song <yhs@fb.com> wrote:
>>
>> Add tests to use the new enum kflag and enum64 API functions
>> in selftest btf_write.
>>
>> Signed-off-by: Yonghong Song <yhs@fb.com>
>> ---
>>   tools/testing/selftests/bpf/btf_helpers.c     |  21 +++-
>>   .../selftests/bpf/prog_tests/btf_write.c      | 114 +++++++++++++-----
>>   2 files changed, 105 insertions(+), 30 deletions(-)
> 
> [...]
> 
>> @@ -307,6 +308,48 @@ static void gen_btf(struct btf *btf)
>>          ASSERT_EQ(t->type, 1, "tag_type");
>>          ASSERT_STREQ(btf_type_raw_dump(btf, 20),
>>                       "[20] TYPE_TAG 'tag1' type_id=1", "raw_dump");
>> +
>> +       /* ENUM64 */
>> +       id = btf__add_enum64(btf, "e1", 8, true);
>> +       ASSERT_EQ(id, 21, "enum64_id");
>> +       err = btf__add_enum64_value(btf, "v1", -1);
>> +       ASSERT_OK(err, "v1_res");
>> +       err = btf__add_enum64_value(btf, "v2", 0x123456789); /* 4886718345 */
>> +       ASSERT_OK(err, "v2_res");
>> +       t = btf__type_by_id(btf, 21);
>> +       ASSERT_STREQ(btf__str_by_offset(btf, t->name_off), "e1", "enum64_name");
>> +       ASSERT_EQ(btf_kind(t), BTF_KIND_ENUM64, "enum64_kind");
>> +       ASSERT_EQ(btf_vlen(t), 2, "enum64_vlen");
>> +       ASSERT_EQ(t->size, 8, "enum64_sz");
>> +       v64 = btf_enum64(t) + 0;
>> +       ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v1", "v1_name");
>> +       ASSERT_EQ(v64->val_hi32, 0xffffffff, "v1_val");
>> +       ASSERT_EQ(v64->val_lo32, 0xffffffff, "v1_val");
>> +       v64 = btf_enum64(t) + 1;
>> +       ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v2", "v2_name");
>> +       ASSERT_EQ(v64->val_hi32, 0x1, "v2_val");
>> +       ASSERT_EQ(v64->val_lo32, 0x23456789, "v2_val");
>> +       ASSERT_STREQ(btf_type_raw_dump(btf, 21),
>> +                    "[21] ENUM64 'e1' size=8 vlen=2\n"
> 
> we should emit and validate kflag for enum/enum64. Or maybe
> "encoding=SIGNED|UNSIGNED" to match INT's output, not sure which one
> is best, but we probably want to make sure that kflag is reflected in
> bpftool and selftests output, right?

My intention is the value print out itself will show it is signed or
unsigned as below. But it doesn't hurt to explicit print out kflag as 
well. Will do.

> 
>> +                    "\t'v1' val=-1\n"
>> +                    "\t'v2' val=4886718345", "raw_dump");
>> +
>> +       id = btf__add_enum64(btf, "e1", 8, false);
>> +       ASSERT_EQ(id, 22, "enum64_id");
>> +       err = btf__add_enum64_value(btf, "v1", 0xffffffffFFFFFFFF); /* 18446744073709551615 */
>> +       ASSERT_OK(err, "v1_res");
>> +       t = btf__type_by_id(btf, 22);
>> +       ASSERT_STREQ(btf__str_by_offset(btf, t->name_off), "e1", "enum64_name");
>> +       ASSERT_EQ(btf_kind(t), BTF_KIND_ENUM64, "enum64_kind");
>> +       ASSERT_EQ(btf_vlen(t), 1, "enum64_vlen");
>> +       ASSERT_EQ(t->size, 8, "enum64_sz");
>> +       v64 = btf_enum64(t) + 0;
>> +       ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v1", "v1_name");
>> +       ASSERT_EQ(v64->val_hi32, 0xffffffff, "v1_val");
>> +       ASSERT_EQ(v64->val_lo32, 0xffffffff, "v1_val");
>> +       ASSERT_STREQ(btf_type_raw_dump(btf, 22),
>> +                    "[22] ENUM64 'e1' size=8 vlen=1\n"
>> +                    "\t'v1' val=18446744073709551615", "raw_dump");
>>   }
>>
>>   static void test_btf_add()
> 
> [...]
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/btf_helpers.c b/tools/testing/selftests/bpf/btf_helpers.c
index b5941d514e17..335ddd485f26 100644
--- a/tools/testing/selftests/bpf/btf_helpers.c
+++ b/tools/testing/selftests/bpf/btf_helpers.c
@@ -26,11 +26,12 @@  static const char * const btf_kind_str_mapping[] = {
 	[BTF_KIND_FLOAT]	= "FLOAT",
 	[BTF_KIND_DECL_TAG]	= "DECL_TAG",
 	[BTF_KIND_TYPE_TAG]	= "TYPE_TAG",
+	[BTF_KIND_ENUM64]	= "ENUM64",
 };
 
 static const char *btf_kind_str(__u16 kind)
 {
-	if (kind > BTF_KIND_TYPE_TAG)
+	if (kind > BTF_KIND_ENUM64)
 		return "UNKNOWN";
 	return btf_kind_str_mapping[kind];
 }
@@ -139,14 +140,30 @@  int fprintf_btf_type_raw(FILE *out, const struct btf *btf, __u32 id)
 	}
 	case BTF_KIND_ENUM: {
 		const struct btf_enum *v = btf_enum(t);
+		const char *fmt_str;
 
+		fmt_str = btf_kflag(t) ? "\n\t'%s' val=%d" : "\n\t'%s' val=%u";
 		fprintf(out, " size=%u vlen=%u", t->size, vlen);
 		for (i = 0; i < vlen; i++, v++) {
-			fprintf(out, "\n\t'%s' val=%u",
+			fprintf(out, fmt_str,
 				btf_str(btf, v->name_off), v->val);
 		}
 		break;
 	}
+	case BTF_KIND_ENUM64: {
+		const struct btf_enum64 *v = btf_enum64(t);
+		const char *fmt_str;
+
+		fmt_str = btf_kflag(t) ? "\n\t'%s' val=%lld" : "\n\t'%s' val=%llu";
+
+		fprintf(out, " size=%u vlen=%u", t->size, vlen);
+		for (i = 0; i < vlen; i++, v++) {
+			fprintf(out, fmt_str,
+				btf_str(btf, v->name_off),
+				((__u64)v->val_hi32 << 32) | v->val_lo32);
+		}
+		break;
+	}
 	case BTF_KIND_FWD:
 		fprintf(out, " fwd_kind=%s", btf_kflag(t) ? "union" : "struct");
 		break;
diff --git a/tools/testing/selftests/bpf/prog_tests/btf_write.c b/tools/testing/selftests/bpf/prog_tests/btf_write.c
index addf99c05896..b4a6b78e94f2 100644
--- a/tools/testing/selftests/bpf/prog_tests/btf_write.c
+++ b/tools/testing/selftests/bpf/prog_tests/btf_write.c
@@ -9,6 +9,7 @@  static void gen_btf(struct btf *btf)
 	const struct btf_var_secinfo *vi;
 	const struct btf_type *t;
 	const struct btf_member *m;
+	const struct btf_enum64 *v64;
 	const struct btf_enum *v;
 	const struct btf_param *p;
 	int id, err, str_off;
@@ -307,6 +308,48 @@  static void gen_btf(struct btf *btf)
 	ASSERT_EQ(t->type, 1, "tag_type");
 	ASSERT_STREQ(btf_type_raw_dump(btf, 20),
 		     "[20] TYPE_TAG 'tag1' type_id=1", "raw_dump");
+
+	/* ENUM64 */
+	id = btf__add_enum64(btf, "e1", 8, true);
+	ASSERT_EQ(id, 21, "enum64_id");
+	err = btf__add_enum64_value(btf, "v1", -1);
+	ASSERT_OK(err, "v1_res");
+	err = btf__add_enum64_value(btf, "v2", 0x123456789); /* 4886718345 */
+	ASSERT_OK(err, "v2_res");
+	t = btf__type_by_id(btf, 21);
+	ASSERT_STREQ(btf__str_by_offset(btf, t->name_off), "e1", "enum64_name");
+	ASSERT_EQ(btf_kind(t), BTF_KIND_ENUM64, "enum64_kind");
+	ASSERT_EQ(btf_vlen(t), 2, "enum64_vlen");
+	ASSERT_EQ(t->size, 8, "enum64_sz");
+	v64 = btf_enum64(t) + 0;
+	ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v1", "v1_name");
+	ASSERT_EQ(v64->val_hi32, 0xffffffff, "v1_val");
+	ASSERT_EQ(v64->val_lo32, 0xffffffff, "v1_val");
+	v64 = btf_enum64(t) + 1;
+	ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v2", "v2_name");
+	ASSERT_EQ(v64->val_hi32, 0x1, "v2_val");
+	ASSERT_EQ(v64->val_lo32, 0x23456789, "v2_val");
+	ASSERT_STREQ(btf_type_raw_dump(btf, 21),
+		     "[21] ENUM64 'e1' size=8 vlen=2\n"
+		     "\t'v1' val=-1\n"
+		     "\t'v2' val=4886718345", "raw_dump");
+
+	id = btf__add_enum64(btf, "e1", 8, false);
+	ASSERT_EQ(id, 22, "enum64_id");
+	err = btf__add_enum64_value(btf, "v1", 0xffffffffFFFFFFFF); /* 18446744073709551615 */
+	ASSERT_OK(err, "v1_res");
+	t = btf__type_by_id(btf, 22);
+	ASSERT_STREQ(btf__str_by_offset(btf, t->name_off), "e1", "enum64_name");
+	ASSERT_EQ(btf_kind(t), BTF_KIND_ENUM64, "enum64_kind");
+	ASSERT_EQ(btf_vlen(t), 1, "enum64_vlen");
+	ASSERT_EQ(t->size, 8, "enum64_sz");
+	v64 = btf_enum64(t) + 0;
+	ASSERT_STREQ(btf__str_by_offset(btf, v64->name_off), "v1", "v1_name");
+	ASSERT_EQ(v64->val_hi32, 0xffffffff, "v1_val");
+	ASSERT_EQ(v64->val_lo32, 0xffffffff, "v1_val");
+	ASSERT_STREQ(btf_type_raw_dump(btf, 22),
+		     "[22] ENUM64 'e1' size=8 vlen=1\n"
+		     "\t'v1' val=18446744073709551615", "raw_dump");
 }
 
 static void test_btf_add()
@@ -348,7 +391,12 @@  static void test_btf_add()
 		"\ttype_id=1 offset=4 size=8",
 		"[18] DECL_TAG 'tag1' type_id=16 component_idx=-1",
 		"[19] DECL_TAG 'tag2' type_id=14 component_idx=1",
-		"[20] TYPE_TAG 'tag1' type_id=1");
+		"[20] TYPE_TAG 'tag1' type_id=1",
+		"[21] ENUM64 'e1' size=8 vlen=2\n"
+		"\t'v1' val=-1\n"
+		"\t'v2' val=4886718345",
+		"[22] ENUM64 'e1' size=8 vlen=1\n"
+		"\t'v1' val=18446744073709551615");
 
 	btf__free(btf);
 }
@@ -370,7 +418,7 @@  static void test_btf_add_btf()
 	gen_btf(btf2);
 
 	id = btf__add_btf(btf1, btf2);
-	if (!ASSERT_EQ(id, 21, "id"))
+	if (!ASSERT_EQ(id, 23, "id"))
 		goto cleanup;
 
 	VALIDATE_RAW_BTF(
@@ -403,36 +451,46 @@  static void test_btf_add_btf()
 		"[18] DECL_TAG 'tag1' type_id=16 component_idx=-1",
 		"[19] DECL_TAG 'tag2' type_id=14 component_idx=1",
 		"[20] TYPE_TAG 'tag1' type_id=1",
+		"[21] ENUM64 'e1' size=8 vlen=2\n"
+		"\t'v1' val=-1\n"
+		"\t'v2' val=4886718345",
+		"[22] ENUM64 'e1' size=8 vlen=1\n"
+		"\t'v1' val=18446744073709551615",
 
 		/* types appended from the second BTF */
-		"[21] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
-		"[22] PTR '(anon)' type_id=21",
-		"[23] CONST '(anon)' type_id=25",
-		"[24] VOLATILE '(anon)' type_id=23",
-		"[25] RESTRICT '(anon)' type_id=24",
-		"[26] ARRAY '(anon)' type_id=22 index_type_id=21 nr_elems=10",
-		"[27] STRUCT 's1' size=8 vlen=2\n"
-		"\t'f1' type_id=21 bits_offset=0\n"
-		"\t'f2' type_id=21 bits_offset=32 bitfield_size=16",
-		"[28] UNION 'u1' size=8 vlen=1\n"
-		"\t'f1' type_id=21 bits_offset=0 bitfield_size=16",
-		"[29] ENUM 'e1' size=4 vlen=2\n"
+		"[23] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED",
+		"[24] PTR '(anon)' type_id=23",
+		"[25] CONST '(anon)' type_id=27",
+		"[26] VOLATILE '(anon)' type_id=25",
+		"[27] RESTRICT '(anon)' type_id=26",
+		"[28] ARRAY '(anon)' type_id=24 index_type_id=23 nr_elems=10",
+		"[29] STRUCT 's1' size=8 vlen=2\n"
+		"\t'f1' type_id=23 bits_offset=0\n"
+		"\t'f2' type_id=23 bits_offset=32 bitfield_size=16",
+		"[30] UNION 'u1' size=8 vlen=1\n"
+		"\t'f1' type_id=23 bits_offset=0 bitfield_size=16",
+		"[31] ENUM 'e1' size=4 vlen=2\n"
 		"\t'v1' val=1\n"
 		"\t'v2' val=2",
-		"[30] FWD 'struct_fwd' fwd_kind=struct",
-		"[31] FWD 'union_fwd' fwd_kind=union",
-		"[32] ENUM 'enum_fwd' size=4 vlen=0",
-		"[33] TYPEDEF 'typedef1' type_id=21",
-		"[34] FUNC 'func1' type_id=35 linkage=global",
-		"[35] FUNC_PROTO '(anon)' ret_type_id=21 vlen=2\n"
-		"\t'p1' type_id=21\n"
-		"\t'p2' type_id=22",
-		"[36] VAR 'var1' type_id=21, linkage=global-alloc",
-		"[37] DATASEC 'datasec1' size=12 vlen=1\n"
-		"\ttype_id=21 offset=4 size=8",
-		"[38] DECL_TAG 'tag1' type_id=36 component_idx=-1",
-		"[39] DECL_TAG 'tag2' type_id=34 component_idx=1",
-		"[40] TYPE_TAG 'tag1' type_id=21");
+		"[32] FWD 'struct_fwd' fwd_kind=struct",
+		"[33] FWD 'union_fwd' fwd_kind=union",
+		"[34] ENUM 'enum_fwd' size=4 vlen=0",
+		"[35] TYPEDEF 'typedef1' type_id=23",
+		"[36] FUNC 'func1' type_id=37 linkage=global",
+		"[37] FUNC_PROTO '(anon)' ret_type_id=23 vlen=2\n"
+		"\t'p1' type_id=23\n"
+		"\t'p2' type_id=24",
+		"[38] VAR 'var1' type_id=23, linkage=global-alloc",
+		"[39] DATASEC 'datasec1' size=12 vlen=1\n"
+		"\ttype_id=23 offset=4 size=8",
+		"[40] DECL_TAG 'tag1' type_id=38 component_idx=-1",
+		"[41] DECL_TAG 'tag2' type_id=36 component_idx=1",
+		"[42] TYPE_TAG 'tag1' type_id=23",
+		"[43] ENUM64 'e1' size=8 vlen=2\n"
+		"\t'v1' val=-1\n"
+		"\t'v2' val=4886718345",
+		"[44] ENUM64 'e1' size=8 vlen=1\n"
+		"\t'v1' val=18446744073709551615");
 
 cleanup:
 	btf__free(btf1);