Re: [PATCH bpf-next v2 06/18] libbpf: Add enum64 deduplication support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, May 13, 2022 at 8:13 PM Yonghong Song <yhs@xxxxxx> wrote:
>
> Add enum64 deduplication support. BTF_KIND_ENUM64 handling
> is very similar to BTF_KIND_ENUM.
>
> Signed-off-by: Yonghong Song <yhs@xxxxxx>
> ---
>  tools/lib/bpf/btf.c | 55 +++++++++++++++++++++++++++++++++------------
>  tools/lib/bpf/btf.h |  5 +++++
>  2 files changed, 46 insertions(+), 14 deletions(-)
>

[...]

> +static bool btf_equal_enum64_val(struct btf_type *t1, struct btf_type *t2)
> +{
> +       const struct btf_enum64 *m1, *m2;
> +       __u16 vlen = btf_vlen(t1);
> +       int i;
> +
> +       m1 = btf_enum64(t1);
> +       m2 = btf_enum64(t2);
> +       for (i = 0; i < vlen; i++) {
> +               if (m1->name_off != m2->name_off || m1->val_lo32 != m2->val_lo32 ||
> +                   m1->val_hi32 != m2->val_hi32)
> +                       return false;
> +               m1++;
> +               m2++;
> +       }
> +       return true;
> +}
> +
> +/* Check structural equality of two ENUMs. */
> +static bool btf_equal_enum_or_enum64(struct btf_type *t1, struct btf_type *t2)

I find this helper quite confusing. It implies it can compare any enum
or enum64 with each other, but it really allows only enum vs enum and
enum64 vs enum64 (as it should!). Let's keep
btf_equal_enum()/btf_compat_enum() completely intact and add
btf_equal_enum64()/btf_compat_enum64() separately (few lines of
copy-pasted code is totally fine to keep them separate, IMO). See
below.

> +{
> +       if (!btf_equal_common(t1, t2))
> +               return false;
> +
> +       if (btf_is_enum(t1))
> +               return btf_equal_enum32_val(t1, t2);
> +       return btf_equal_enum64_val(t1, t2);
> +}
> +
>  static inline bool btf_is_enum_fwd(struct btf_type *t)
>  {
> -       return btf_is_enum(t) && btf_vlen(t) == 0;
> +       return btf_type_is_any_enum(t) && btf_vlen(t) == 0;
>  }
>
> -static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2)
> +static bool btf_compat_enum_or_enum64(struct btf_type *t1, struct btf_type *t2)
>  {
>         if (!btf_is_enum_fwd(t1) && !btf_is_enum_fwd(t2))
> -               return btf_equal_enum(t1, t2);
> +               return btf_equal_enum_or_enum64(t1, t2);
>         /* ignore vlen when comparing */
>         return t1->name_off == t2->name_off &&
>                (t1->info & ~0xffff) == (t2->info & ~0xffff) &&
> @@ -3829,6 +3853,7 @@ static int btf_dedup_prep(struct btf_dedup *d)
>                         h = btf_hash_int_decl_tag(t);
>                         break;
>                 case BTF_KIND_ENUM:
> +               case BTF_KIND_ENUM64:
>                         h = btf_hash_enum(t);
>                         break;
>                 case BTF_KIND_STRUCT:
> @@ -3898,15 +3923,16 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
>                 break;
>
>         case BTF_KIND_ENUM:
> +       case BTF_KIND_ENUM64:
>                 h = btf_hash_enum(t);
>                 for_each_dedup_cand(d, hash_entry, h) {
>                         cand_id = (__u32)(long)hash_entry->value;
>                         cand = btf_type_by_id(d->btf, cand_id);
> -                       if (btf_equal_enum(t, cand)) {
> +                       if (btf_equal_enum_or_enum64(t, cand)) {

I'd rather have this enum vs enum64 distinction right here:

if ((btf_is_enum(t) && btf_equal_enum(t, cand)) ||
    (btf_is_enum64(t) && btf_equal_enum64(t, cand))) { ... }

>                                 new_id = cand_id;
>                                 break;
>                         }
> -                       if (btf_compat_enum(t, cand)) {
> +                       if (btf_compat_enum_or_enum64(t, cand)) {

and same here with (btf_is_enum && btf_compat_enum) || (btf_is_num64
&& btf_compat_enum64) ?

Basically, I'd like to avoid worrying if we are accidentally mixing
enum and enum64 or not. WDYT?

>                                 if (btf_is_enum_fwd(t)) {
>                                         /* resolve fwd to full enum */
>                                         new_id = cand_id;
> @@ -4211,7 +4237,8 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
>                 return btf_equal_int_tag(cand_type, canon_type);
>
>         case BTF_KIND_ENUM:
> -               return btf_compat_enum(cand_type, canon_type);
> +       case BTF_KIND_ENUM64:
> +               return btf_compat_enum_or_enum64(cand_type, canon_type);
>

and here we just know whether we need btf_compat_enum vs btf_compat_enum64.


>         case BTF_KIND_FWD:
>         case BTF_KIND_FLOAT:
> diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h
> index a41463bf9060..b22c648c69ff 100644
> --- a/tools/lib/bpf/btf.h
> +++ b/tools/lib/bpf/btf.h
> @@ -531,6 +531,11 @@ static inline bool btf_is_type_tag(const struct btf_type *t)
>         return btf_kind(t) == BTF_KIND_TYPE_TAG;
>  }
>
> +static inline bool btf_type_is_any_enum(const struct btf_type *t)
> +{
> +       return btf_is_enum(t) || btf_is_enum64(t);
> +}
> +
>  static inline __u8 btf_int_encoding(const struct btf_type *t)
>  {
>         return BTF_INT_ENCODING(*(__u32 *)(t + 1));
> --
> 2.30.2
>



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux