On Thu, Dec 19, 2019 at 11:22:17PM -0800, Martin Lau wrote: > [ ... ] > > > > +/* __bpf_##_name (e.g. __bpf_tcp_congestion_ops) is the map's value > > > + * exposed to the userspace and its btf-type-id is stored > > > + * at the map->btf_vmlinux_value_type_id. > > > + * > > > + * The *_name##_dummy is to ensure the BTF type is emitted. > > > + */ > > > + > > > #define BPF_STRUCT_OPS_TYPE(_name) \ > > > -extern struct bpf_struct_ops bpf_##_name; > > > +extern struct bpf_struct_ops bpf_##_name; \ > > > + \ > > > +static struct __bpf_##_name { \ > > > + BPF_STRUCT_OPS_COMMON_VALUE; \ > > > + struct _name data ____cacheline_aligned_in_smp; \ > > > +} *_name##_dummy; > > > > There are other ways to retain types in debug info without > > creating new variables. For example, you can use it in a cast > > like > > (void *)(struct __bpf_##_name *)v > hmm... What is v? Got it. "v" could be any dummy pointer in a function. I will use (void) instead of (void *) to avoid compiler warning. > > > Not sure whether we could easily find a place for such casting or not. This can be done in bpf_struct_ops_init(). Thanks for the tips!