[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20181215214915.gmrecxukscjyj465@kafai-mbp>
Date: Sat, 15 Dec 2018 21:49:17 +0000
From: Martin Lau <kafai@...com>
To: Yonghong Song <yhs@...com>
CC: "netdev@...r.kernel.org" <netdev@...r.kernel.org>,
Alexei Starovoitov <ast@...com>,
Daniel Borkmann <daniel@...earbox.net>,
Kernel Team <Kernel-team@...com>
Subject: Re: [PATCH bpf-next v2 8/8] tools: bpftool: support pretty print with
kind_flag set
On Fri, Dec 14, 2018 at 03:34:34PM -0800, Yonghong Song wrote:
> The following example shows map pretty print with structures
> which include bitfield members.
>
> enum A { A1, A2, A3, A4, A5 };
> typedef enum A ___A;
> struct tmp_t {
> char a1:4;
> int a2:4;
> int :4;
> __u32 a3:4;
> int b;
> ___A b1:4;
> enum A b2:4;
> };
> struct bpf_map_def SEC("maps") tmpmap = {
> .type = BPF_MAP_TYPE_ARRAY,
> .key_size = sizeof(__u32),
> .value_size = sizeof(struct tmp_t),
> .max_entries = 1,
> };
> BPF_ANNOTATE_KV_PAIR(tmpmap, int, struct tmp_t);
>
> and the following map update in the bpf program:
>
> key = 0;
> struct tmp_t t = {};
> t.a1 = 2;
> t.a2 = 4;
> t.a3 = 6;
> t.b = 7;
> t.b1 = 8;
> t.b2 = 10;
> bpf_map_update_elem(&tmpmap, &key, &t, 0);
>
> With this patch, I am able to print out the map values
> correctly with this patch:
> bpftool map dump id 187
> [{
> "key": 0,
> "value": {
> "a1": 0x2,
> "a2": 0x4,
> "a3": 0x6,
> "b": 7,
> "b1": 0x8,
> "b2": 0xa
> }
> }
> ]
>
> The following example shows forward type can be properly
> printed in function prototype with modified tst_btf_haskv.c.
>
> struct t;
> union u;
>
> __attribute__((noinline))
> static int test_long_fname_1(struct dummy_tracepoint_args *arg,
> struct t *p1, union u *p2,
> __u32 unused)
> ...
> int _dummy_tracepoint(struct dummy_tracepoint_args *arg) {
> return test_long_fname_1(arg, 0, 0);
> }
>
> $ bpftool p d xlated id 24
> ...
> int test_long_fname_1(struct dummy_tracepoint_args * arg,
> struct t * p1, union u * p2,
> __u32 unused)
> ...
>
> Signed-off-by: Yonghong Song <yhs@...com>
> ---
> tools/bpf/bpftool/btf_dumper.c | 36 +++++++++++++++++++++++++---------
> 1 file changed, 27 insertions(+), 9 deletions(-)
>
> diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c
> index ec1da87c3d65..23fc6a84d82b 100644
> --- a/tools/bpf/bpftool/btf_dumper.c
> +++ b/tools/bpf/bpftool/btf_dumper.c
> @@ -190,6 +190,7 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
> const struct btf_type *t;
> struct btf_member *m;
> const void *data_off;
> + int kind_flag;
> int ret = 0;
> int i, vlen;
>
> @@ -197,18 +198,32 @@ static int btf_dumper_struct(const struct btf_dumper *d, __u32 type_id,
> if (!t)
> return -EINVAL;
>
> + kind_flag = BTF_INFO_KFLAG(t->info);
> vlen = BTF_INFO_VLEN(t->info);
> jsonw_start_object(d->jw);
> m = (struct btf_member *)(t + 1);
>
> for (i = 0; i < vlen; i++) {
> - data_off = data + BITS_ROUNDDOWN_BYTES(m[i].offset);
> + __u32 bit_offset = m[i].offset;
Without always checking the kind_flag first, here is an example
that accessing the .offset looks incorrect at the first glance.
> + __u32 bitfield_size = 0;
> +
> + if (kind_flag) {
but then I noticed it is fine here ;)
> + bitfield_size = BTF_MEMBER_BITFIELD_SIZE(bit_offset);
> + bit_offset = BTF_MEMBER_BIT_OFFSET(bit_offset);
> + }
> +
> jsonw_name(d->jw, btf__name_by_offset(d->btf, m[i].name_off));
> - ret = btf_dumper_do_type(d, m[i].type,
> - BITS_PER_BYTE_MASKED(m[i].offset),
> - data_off);
> - if (ret)
> - break;
> + if (bitfield_size) {
> + btf_dumper_bitfield(bitfield_size, bit_offset,
> + data, d->jw, d->is_plain_text);
> + } else {
> + data_off = data + BITS_ROUNDDOWN_BYTES(bit_offset);
> + ret = btf_dumper_do_type(d, m[i].type,
> + BITS_PER_BYTE_MASKED(bit_offset),
> + data_off);
> + if (ret)
> + break;
> + }
> }
>
> jsonw_end_object(d->jw);
> @@ -295,6 +310,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
>
> switch (BTF_INFO_KIND(t->info)) {
> case BTF_KIND_INT:
> + case BTF_KIND_TYPEDEF:
> BTF_PRINT_ARG("%s ", btf__name_by_offset(btf, t->name_off));
> break;
> case BTF_KIND_STRUCT:
> @@ -318,10 +334,11 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
> BTF_PRINT_TYPE(t->type);
> BTF_PRINT_ARG("* ");
> break;
> - case BTF_KIND_UNKN:
> case BTF_KIND_FWD:
> - case BTF_KIND_TYPEDEF:
hmm.... Is this TYPEDEF change related to this patch?
If not, a comment in the commit message would help.
Other than that,
Acked-by: Martin KaFai Lau <kafai@...com>
> - return -1;
> + BTF_PRINT_ARG("%s %s ",
> + BTF_INFO_KFLAG(t->info) ? "union" : "struct",
> + btf__name_by_offset(btf, t->name_off));
> + break;
> case BTF_KIND_VOLATILE:
> BTF_PRINT_ARG("volatile ");
> BTF_PRINT_TYPE(t->type);
> @@ -345,6 +362,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id,
> if (pos == -1)
> return -1;
> break;
> + case BTF_KIND_UNKN:
> default:
> return -1;
> }
> --
> 2.17.1
>
Powered by blists - more mailing lists