bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
To: bpf@vger.kernel.org
Cc: Yonghong Song <yhs@fb.com>
Subject: BTF type tags not emitted properly when using macros
Date: Sun, 20 Feb 2022 12:43:33 +0530	[thread overview]
Message-ID: <20220220071333.sltv4jrwniool2qy@apollo.legion> (raw)

Hi list,

I noticed another problem in LLVM HEAD wrt BTF type tags.

When I have a file like bad.c:

 ; cat bad.c
#define __kptr __attribute__((btf_type_tag("btf_id")))
#define __kptr_ref __kptr __attribute__((btf_type_tag("ref")))
#define __kptr_percpu __kptr __attribute__((btf_type_tag("percpu")))
#define __kptr_user __kptr __attribute__((btf_type_tag("user")))

struct map_value {
        int __kptr *a;
        int __kptr_ref *b;
        int __kptr_percpu *c;
        int __kptr_user *d;
};

struct map_value *func(void);

int main(void)
{
        struct map_value *p = func();
        return *p->a + *p->b + *p->c + *p->d;
}

All tags are not emitted to BTF (neither are they there in llvm-dwarfdump output):

 ; ./src/linux/kptr-map/tools/bpf/bpftool/bpftool btf dump file bad.o format raw
[1] FUNC_PROTO '(anon)' ret_type_id=2 vlen=0
[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
[3] FUNC 'main' type_id=1 linkage=global
[4] FUNC_PROTO '(anon)' ret_type_id=5 vlen=0
[5] PTR '(anon)' type_id=6
[6] STRUCT 'map_value' size=32 vlen=4
        'a' type_id=8 bits_offset=0
        'b' type_id=11 bits_offset=64
        'c' type_id=11 bits_offset=128
        'd' type_id=11 bits_offset=192
[7] TYPE_TAG 'btf_id' type_id=2
[8] PTR '(anon)' type_id=7
[9] TYPE_TAG 'btf_id' type_id=2
[10] TYPE_TAG 'ref' type_id=9
[11] PTR '(anon)' type_id=10
[12] FUNC 'func' type_id=4 linkage=extern

Notice that only btf_id (__kptr) and btf_id + ref (__kptr_ref) are emitted
properly, and then rest of members use type_id=11, instead of emitting more type
tags.

When I use a mix of macro and direct attributes, or just attributes, it does work:

; cat good.c
#define __kptr __attribute__((btf_type_tag("btf_id")))

struct map_value {
        int __kptr *a;
        int __kptr __attribute__((btf_type_tag("ref"))) *b;
        int __kptr __attribute__((btf_type_tag("percpu"))) *c;
        int __kptr __attribute__((btf_type_tag("user"))) *d;
};

struct map_value *func(void);

int main(void)
{
        struct map_value *p = func();
        return *p->a + *p->b + *p->c + *p->d;
}

Now all tags are there in BTF:

 ; ./src/linux/kptr-map/tools/bpf/bpftool/bpftool btf dump file good.o format raw
[1] FUNC_PROTO '(anon)' ret_type_id=2 vlen=0
[2] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
[3] FUNC 'main' type_id=1 linkage=global
[4] FUNC_PROTO '(anon)' ret_type_id=5 vlen=0
[5] PTR '(anon)' type_id=6
[6] STRUCT 'map_value' size=32 vlen=4
        'a' type_id=8 bits_offset=0
        'b' type_id=11 bits_offset=64
        'c' type_id=14 bits_offset=128
        'd' type_id=17 bits_offset=192
[7] TYPE_TAG 'btf_id' type_id=2
[8] PTR '(anon)' type_id=7
[9] TYPE_TAG 'btf_id' type_id=2
[10] TYPE_TAG 'ref' type_id=9
[11] PTR '(anon)' type_id=10
[12] TYPE_TAG 'btf_id' type_id=2
[13] TYPE_TAG 'percpu' type_id=12
[14] PTR '(anon)' type_id=13
[15] TYPE_TAG 'btf_id' type_id=2
[16] TYPE_TAG 'user' type_id=15
[17] PTR '(anon)' type_id=16
[18] FUNC 'func' type_id=4 linkage=extern

In both cases, the preprocessed source (using -E) looks to be the same:

 ; /home/kkd/src/llvm-project/llvm/build/bin/clang --target=bpf -g -O2 -c bad.c -E
# 1 "bad.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 323 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "bad.c" 2

struct map_value {
 int __attribute__((btf_type_tag("btf_id"))) *a;
 int __attribute__((btf_type_tag("btf_id"))) __attribute__((btf_type_tag("ref"))) *b;
 int __attribute__((btf_type_tag("btf_id"))) __attribute__((btf_type_tag("percpu"))) *c;
 int __attribute__((btf_type_tag("btf_id"))) __attribute__((btf_type_tag("user"))) *d;
};

struct map_value *func(void);

int main(void)
{
 struct map_value *p = func();
 return *p->a + *p->b + *p->c + *p->d;
}

 ; /home/kkd/src/llvm-project/llvm/build/bin/clang --target=bpf -g -O2 -c good.c -E
# 1 "good.c"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 323 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "good.c" 2

struct map_value {
 int __attribute__((btf_type_tag("btf_id"))) *a;
 int __attribute__((btf_type_tag("btf_id"))) __attribute__((btf_type_tag("ref"))) *b;
 int __attribute__((btf_type_tag("btf_id"))) __attribute__((btf_type_tag("percpu"))) *c;
 int __attribute__((btf_type_tag("btf_id"))) __attribute__((btf_type_tag("user"))) *d;
};

struct map_value *func(void);

int main(void)
{
 struct map_value *p = func();
 return *p->a + *p->b + *p->c + *p->d;
}

--

Please let me know if I made some dumb mistake.

 ; /home/kkd/src/llvm-project/llvm/build/bin/clang --version
clang version 15.0.0 (https://github.com/llvm/llvm-project.git 290e482342826ee4c65bd6d2aece25736d3f0c7b)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/kkd/src/llvm-project/llvm/build/bin

A side note, but it seems it could avoid emitting the same type tag multiple
times to save on space. I.e. in the case of other members, their ref, percpu,
user tag could point to the same btf_id type tag that the first member's
BTF_KIND_PTR points to.

Thanks.
--
Kartikeya

             reply	other threads:[~2022-02-20  7:13 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-02-20  7:13 Kumar Kartikeya Dwivedi [this message]
2022-02-20 19:22 ` BTF type tags not emitted properly when using macros Yonghong Song
2022-02-22  6:55   ` Yonghong Song
2022-03-03  3:05     ` Kumar Kartikeya Dwivedi

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=20220220071333.sltv4jrwniool2qy@apollo.legion \
    --to=memxor@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=yhs@fb.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).