From: "Alexei Starovoitov" <alexei.starovoitov@gmail.com>
To: "Hungyu Lin" <dennylin0707@gmail.com>, <bpf@vger.kernel.org>
Cc: <andrii@kernel.org>, <qmo@kernel.org>, <daniel@iogearbox.net>,
<yonghong.song@linux.dev>, <eddyz87@gmail.com>,
<ihor.solodrai@linux.dev>, <shuah@kernel.org>,
<linux-kselftest@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH bpf-next v4 0/3] Normalize enum values in libbpf and bpftool
Date: Sat, 07 Nov 2026 03:46:21 +0000 [thread overview]
Message-ID: <DMOO53QTDUQ4.2Z9UXMZEPX568@gmail.com> (raw)
In-Reply-To: <20261107020725.36675-1-dennylin0707@gmail.com>
On Fri, Nov 06, 2026 at 06:07 PM Hungyu Lin <dennylin0707@gmail.com> wrote:
> .../bpf/prog_tests/bpftool_map_dump.c | 162 ++++++++++++++++++
> .../selftests/bpf/prog_tests/btf_dump.c | 77 +++++++++
> .../selftests/bpf/prog_tests/map_extra.c | 19 ++
> .../selftests/bpf/progs/test_map_extra.c | 12 ++
> 8 files changed, 293 insertions(+), 10 deletions(-)
selftest are growing too fast.
16 subtests create 16 maps and run bpftool 32 times.
9 of the 16 pass without the fix.
Plain and json output come from the same btf_dumper_enum().
One map with a struct of four enums and one run of bpftool are enough.
The btf_dump.c part below is the test from my reply to the libbpf patch.
Keep patches 1 and 2. Keep the map_extra test.
Instead of the other two files of patch 3 (not even compile tested):
diff --git a/tools/testing/selftests/bpf/prog_tests/bpftool_map_dump.c b/tools/testing/selftests/bpf/prog_tests/bpftool_map_dump.c
index 187b3f7..1c581db 100644
--- a/tools/testing/selftests/bpf/prog_tests/bpftool_map_dump.c
+++ b/tools/testing/selftests/bpf/prog_tests/bpftool_map_dump.c
@@ -7,6 +7,7 @@
#define PIN_PATH "/sys/fs/bpf/test_bpftool_map_dump_sk_storage"
#define QUEUE_PIN_PATH "/sys/fs/bpf/test_bpftool_map_dump_queue"
+#define ENUM_PIN_PATH "/sys/fs/bpf/test_bpftool_map_dump_enum"
#define JSON_ERROR "{\"error\":\"can't dump sk_storage map"
/* An empty socket storage map with an int value. */
@@ -124,10 +125,85 @@ out:
close(map_fd);
}
+struct enums {
+ __u8 u8_name;
+ __s8 s8_name;
+ __u32 u32_num;
+ __u64 u64_num;
+};
+
+/* An array map. Its value is struct enums with an enum behind every member. */
+static int create_enum_map(void)
+{
+ LIBBPF_OPTS(bpf_map_create_opts, opts);
+ struct btf *btf;
+ int fd = -1;
+
+ btf = btf__new_empty();
+ if (!ASSERT_OK_PTR(btf, "btf__new_empty"))
+ return -1;
+
+ btf__add_int(btf, "int", 4, BTF_INT_SIGNED); /* [1] */
+ btf__add_enum(btf, "u8", 1); /* [2] */
+ btf__add_enum_value(btf, "U8_MAX", 0xff);
+ btf__add_enum(btf, "s8", 1); /* [3] */
+ btf__add_enum_value(btf, "S8_NEG", -1);
+ btf__add_enum(btf, "u32", 4); /* [4] */
+ btf__add_enum_value(btf, "U32_ONE", 1);
+ btf__add_enum64(btf, "u64", 8, false); /* [5] */
+ btf__add_enum64_value(btf, "U64_ONE", 1);
+ btf__add_struct(btf, "enums", sizeof(struct enums)); /* [6] */
+ btf__add_field(btf, "u8_name", 2, 0, 0);
+ btf__add_field(btf, "s8_name", 3, 8, 0);
+ btf__add_field(btf, "u32_num", 4, 32, 0);
+ btf__add_field(btf, "u64_num", 5, 64, 0);
+ if (!ASSERT_OK(btf__load_into_kernel(btf), "btf__load_into_kernel"))
+ goto out;
+
+ opts.btf_fd = btf__fd(btf);
+ opts.btf_key_type_id = 1;
+ opts.btf_value_type_id = 6;
+ fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "enums", sizeof(int),
+ sizeof(struct enums), 1, &opts);
+ ASSERT_OK_FD(fd, "bpf_map_create");
+out:
+ btf__free(btf);
+ return fd;
+}
+
+static void test_enum(void)
+{
+ struct enums value = { 0xff, -1, (__u32)-22, (1ULL << 63) | 1 };
+ char output[1024] = {};
+ int map_fd, key = 0, ret;
+
+ map_fd = create_enum_map();
+ if (map_fd < 0)
+ return;
+ if (!ASSERT_OK(bpf_map_update_elem(map_fd, &key, &value, BPF_ANY),
+ "update map"))
+ goto out;
+ if (!ASSERT_OK(bpf_obj_pin(map_fd, ENUM_PIN_PATH), "pin map"))
+ goto out;
+
+ ret = get_bpftool_command_output("-j map dump pinned " ENUM_PIN_PATH,
+ output, sizeof(output));
+ ASSERT_OK(ret, "json dump");
+ ASSERT_HAS_SUBSTR(output,
+ "{\"u8_name\":\"U8_MAX\",\"s8_name\":\"S8_NEG\","
+ "\"u32_num\":4294967274,\"u64_num\":9223372036854775809}",
+ "enum values");
+out:
+ unlink(ENUM_PIN_PATH);
+ close(map_fd);
+}
+
void test_bpftool_map_dump(void)
{
if (test__start_subtest("sk_storage"))
test_sk_storage();
if (test__start_subtest("queue"))
test_queue();
+ if (test__start_subtest("enum"))
+ test_enum();
}
diff --git a/tools/testing/selftests/bpf/prog_tests/btf_dump.c b/tools/testing/selftests/bpf/prog_tests/btf_dump.c
index bfa74db..f126fe3 100644
--- a/tools/testing/selftests/bpf/prog_tests/btf_dump.c
+++ b/tools/testing/selftests/bpf/prog_tests/btf_dump.c
@@ -944,6 +944,9 @@ static void test_btf_dump_typedef_data(struct btf *btf, struct btf_dump *d,
static void test_btf_dump_enum_data(struct btf *btf, struct btf_dump *d,
char *str)
{
+ __u32 high = 0x80000000;
+ __s32 neg = -1;
+
/* enum where enum value does (and does not) exist */
TEST_BTF_DUMP_DATA_C(btf, d, "enum", str, enum bpf_cmd, BTF_F_COMPACT,
BPF_MAP_CREATE);
@@ -975,6 +978,22 @@ static void test_btf_dump_enum_data(struct btf *btf, struct btf_dump *d,
TEST_BTF_DUMP_DATA_OVER(btf, d, "enum", str, enum bpf_cmd,
sizeof(enum bpf_cmd) - 1, "", BPF_MAP_CREATE);
+
+ /* enumerators with bit 31 set in unsigned and in signed enum */
+ ASSERT_GT(btf__add_enum(btf, "test_enum_u32", 4), 0, "add unsigned enum");
+ ASSERT_OK(btf__add_enum_value(btf, "TEST_ENUM_HIGH", 0x80000000), "add TEST_ENUM_HIGH");
+ ASSERT_GT(btf__add_enum(btf, "test_enum_s32", 4), 0, "add signed enum");
+ ASSERT_OK(btf__add_enum_value(btf, "TEST_ENUM_NEG", -1), "add TEST_ENUM_NEG");
+
+ /* btf_dump__dump_type_data() doesn't resize 'd' for the new types */
+ d = btf_dump__new(btf, btf_dump_snprintf, str, NULL);
+ if (!ASSERT_OK_PTR(d, "btf_dump__new"))
+ return;
+ ASSERT_OK(btf_dump_data(btf, d, "test_enum_u32", NULL, 0, &high, 4, str,
+ "(enum test_enum_u32)TEST_ENUM_HIGH"), "dump unsigned enum");
+ ASSERT_OK(btf_dump_data(btf, d, "test_enum_s32", NULL, 0, &neg, 4, str,
+ "(enum test_enum_s32)TEST_ENUM_NEG"), "dump signed enum");
+ btf_dump__free(d);
}
static void test_btf_dump_struct_data(struct btf *btf, struct btf_dump *d,
pw-bot: cr
prev parent reply other threads:[~2026-11-07 3:46 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-07 2:07 [PATCH bpf-next v4 0/3] Normalize enum values in libbpf and bpftool Hungyu Lin
2026-11-07 2:07 ` [PATCH bpf-next v4 1/3] libbpf: Normalize enum values according to signedness Hungyu Lin
2026-11-07 2:07 ` [PATCH bpf-next v4 2/3] bpftool: Preserve unsigned enum values in data dumps Hungyu Lin
2026-11-07 2:07 ` [PATCH bpf-next v4 3/3] selftests/bpf: Cover enum signedness in data dumps and map fields Hungyu Lin
2026-11-07 2:47 ` bot+bpf-ci
2026-11-07 3:46 ` Alexei Starovoitov [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=DMOO53QTDUQ4.2Z9UXMZEPX568@gmail.com \
--to=alexei.starovoitov@gmail.com \
--cc=andrii@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=dennylin0707@gmail.com \
--cc=eddyz87@gmail.com \
--cc=ihor.solodrai@linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=qmo@kernel.org \
--cc=shuah@kernel.org \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.