diff mbox series

[bpf-next,1/2] libbpf: Move core "types_are_compat" logic into relo_core.c

Message ID 20220622173506.860578-2-deso@posteo.net (mailing list archive)
State Changes Requested
Delegated to: BPF
Headers show
Series Deduplicate type compat check | expand

Checks

Context Check Description
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-3 success Logs for Kernel LATEST on z15 with gcc
netdev/tree_selection success Clearly marked for bpf-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 8 this patch: 8
netdev/cc_maintainers warning 6 maintainers not CCed: netdev@vger.kernel.org songliubraving@fb.com yhs@fb.com john.fastabend@gmail.com kafai@fb.com kpsingh@kernel.org
netdev/build_clang success Errors and warnings before: 6 this patch: 6
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 8 this patch: 8
netdev/checkpatch warning WARNING: line length of 81 exceeds 80 columns WARNING: line length of 82 exceeds 80 columns WARNING: line length of 84 exceeds 80 columns WARNING: line length of 89 exceeds 80 columns WARNING: line length of 90 exceeds 80 columns WARNING: line length of 92 exceeds 80 columns WARNING: line length of 96 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-VM_Test-1 success Logs for Kernel LATEST on ubuntu-latest with gcc
bpf/vmtest-bpf-next-VM_Test-2 success Logs for Kernel LATEST on ubuntu-latest with llvm-15

Commit Message

Daniel Müller June 22, 2022, 5:35 p.m. UTC
This change merges the two existing implementations of the
bpf_core_types_are_compat() function into relo_core.c, inheriting the
recursion tracking from the kernel and the usage of
btf_kind_core_compat() from libbpf. The kernel is left untouched and
will be adjusted subsequently.

Signed-off-by: Daniel Müller <deso@posteo.net>
---
 tools/lib/bpf/libbpf.c    | 72 +-----------------------------------
 tools/lib/bpf/relo_core.c | 78 +++++++++++++++++++++++++++++++++++++++
 tools/lib/bpf/relo_core.h |  2 +
 3 files changed, 81 insertions(+), 71 deletions(-)

Comments

Daniel Müller June 22, 2022, 10:19 p.m. UTC | #1
On Wed, Jun 22, 2022 at 05:35:05PM +0000, Daniel Müller wrote:
> diff --git a/tools/lib/bpf/relo_core.c b/tools/lib/bpf/relo_core.c
> index 6ad3c3..e54370 100644
> --- a/tools/lib/bpf/relo_core.c
> +++ b/tools/lib/bpf/relo_core.c
> @@ -141,6 +141,84 @@ static bool core_relo_is_enumval_based(enum bpf_core_relo_kind kind)
>  	}
>  }
>  
> +int bpf_core_types_are_compat_recur(const struct btf *local_btf, __u32 local_id,
> +				    const struct btf *targ_btf, __u32 targ_id, int level)
> +{

[...]

> +
> +		/* tail recurse for return type check */
> +		skip_mods_and_typedefs(local_btf, local_type->type, &local_id);
> +		skip_mods_and_typedefs(targ_btf, targ_type->type, &targ_id);
> +		goto recur;
> +	}
> +	default:
> +		return 0;

I actually left out the pr_warn here (present in libbpf but not the kernel). I
suppose it would be best to carry it over from libbpf?

Thanks,
Daniel
Andrii Nakryiko June 23, 2022, 4:15 a.m. UTC | #2
On Wed, Jun 22, 2022 at 10:35 AM Daniel Müller <deso@posteo.net> wrote:
>
> This change merges the two existing implementations of the
> bpf_core_types_are_compat() function into relo_core.c, inheriting the
> recursion tracking from the kernel and the usage of
> btf_kind_core_compat() from libbpf. The kernel is left untouched and
> will be adjusted subsequently.
>
> Signed-off-by: Daniel Müller <deso@posteo.net>
> ---

I don't feel very strongly about this, but given we are consolidating
kernel and libbpf code, I think it makes sense to do it in one patch.

>  tools/lib/bpf/libbpf.c    | 72 +-----------------------------------
>  tools/lib/bpf/relo_core.c | 78 +++++++++++++++++++++++++++++++++++++++
>  tools/lib/bpf/relo_core.h |  2 +
>  3 files changed, 81 insertions(+), 71 deletions(-)
>

[...]

> -       default:
> -               pr_warn("unexpected kind %s relocated, local [%d], target [%d]\n",
> -                       btf_kind_str(local_type), local_id, targ_id);
> -               return 0;
> -       }
> +       return bpf_core_types_are_compat_recur(local_btf, local_id, targ_btf, targ_id, INT_MAX);

INT_MAX seems like an overkill, let's just hard-code 32 just like we
have for a local recursion limit here?

>  }
>

[...]

>  /*
>   * Turn bpf_core_relo into a low- and high-level spec representation,
>   * validating correctness along the way, as well as calculating resulting
> diff --git a/tools/lib/bpf/relo_core.h b/tools/lib/bpf/relo_core.h
> index 7df0da0..b8998f 100644
> --- a/tools/lib/bpf/relo_core.h
> +++ b/tools/lib/bpf/relo_core.h
> @@ -68,6 +68,8 @@ struct bpf_core_relo_res {
>         __u32 new_type_id;
>  };
>
> +int bpf_core_types_are_compat_recur(const struct btf *local_btf, __u32 local_id,
> +                                   const struct btf *targ_btf, __u32 targ_id, int level);

Just leave it called __bpf_core_types_are_compat like in kernel, it is
clearly an "internal" version of bpf_core_types_are_compat(), so it's
more proper naming convention.


>  int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id,
>                               const struct btf *targ_btf, __u32 targ_id);
>
> --
> 2.30.2
>
Andrii Nakryiko June 23, 2022, 4:15 a.m. UTC | #3
On Wed, Jun 22, 2022 at 3:19 PM Daniel Müller <deso@posteo.net> wrote:
>
> On Wed, Jun 22, 2022 at 05:35:05PM +0000, Daniel Müller wrote:
> > diff --git a/tools/lib/bpf/relo_core.c b/tools/lib/bpf/relo_core.c
> > index 6ad3c3..e54370 100644
> > --- a/tools/lib/bpf/relo_core.c
> > +++ b/tools/lib/bpf/relo_core.c
> > @@ -141,6 +141,84 @@ static bool core_relo_is_enumval_based(enum bpf_core_relo_kind kind)
> >       }
> >  }
> >
> > +int bpf_core_types_are_compat_recur(const struct btf *local_btf, __u32 local_id,
> > +                                 const struct btf *targ_btf, __u32 targ_id, int level)
> > +{
>
> [...]
>
> > +
> > +             /* tail recurse for return type check */
> > +             skip_mods_and_typedefs(local_btf, local_type->type, &local_id);
> > +             skip_mods_and_typedefs(targ_btf, targ_type->type, &targ_id);
> > +             goto recur;
> > +     }
> > +     default:
> > +             return 0;
>
> I actually left out the pr_warn here (present in libbpf but not the kernel). I
> suppose it would be best to carry it over from libbpf?

Yes, please.


>
> Thanks,
> Daniel
Daniel Müller June 23, 2022, 6:13 p.m. UTC | #4
On Wed, Jun 22, 2022 at 09:15:01PM -0700, Andrii Nakryiko wrote:
> On Wed, Jun 22, 2022 at 10:35 AM Daniel Müller <deso@posteo.net> wrote:
> >
> > This change merges the two existing implementations of the
> > bpf_core_types_are_compat() function into relo_core.c, inheriting the
> > recursion tracking from the kernel and the usage of
> > btf_kind_core_compat() from libbpf. The kernel is left untouched and
> > will be adjusted subsequently.
> >
> > Signed-off-by: Daniel Müller <deso@posteo.net>
> > ---
> 
> I don't feel very strongly about this, but given we are consolidating
> kernel and libbpf code, I think it makes sense to do it in one patch.

Sure.


> >  tools/lib/bpf/libbpf.c    | 72 +-----------------------------------
> >  tools/lib/bpf/relo_core.c | 78 +++++++++++++++++++++++++++++++++++++++
> >  tools/lib/bpf/relo_core.h |  2 +
> >  3 files changed, 81 insertions(+), 71 deletions(-)
> >
> 
> [...]
> 
> > -       default:
> > -               pr_warn("unexpected kind %s relocated, local [%d], target [%d]\n",
> > -                       btf_kind_str(local_type), local_id, targ_id);
> > -               return 0;
> > -       }
> > +       return bpf_core_types_are_compat_recur(local_btf, local_id, targ_btf, targ_id, INT_MAX);
> 
> INT_MAX seems like an overkill, let's just hard-code 32 just like we
> have for a local recursion limit here?

Okay.

> >  }
> >
> 
> [...]
> 
> >  /*
> >   * Turn bpf_core_relo into a low- and high-level spec representation,
> >   * validating correctness along the way, as well as calculating resulting
> > diff --git a/tools/lib/bpf/relo_core.h b/tools/lib/bpf/relo_core.h
> > index 7df0da0..b8998f 100644
> > --- a/tools/lib/bpf/relo_core.h
> > +++ b/tools/lib/bpf/relo_core.h
> > @@ -68,6 +68,8 @@ struct bpf_core_relo_res {
> >         __u32 new_type_id;
> >  };
> >
> > +int bpf_core_types_are_compat_recur(const struct btf *local_btf, __u32 local_id,
> > +                                   const struct btf *targ_btf, __u32 targ_id, int level);
> 
> Just leave it called __bpf_core_types_are_compat like in kernel, it is
> clearly an "internal" version of bpf_core_types_are_compat(), so it's
> more proper naming convention.

Sounds good.

[...]

Thanks,
Daniel
diff mbox series

Patch

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 49e359c..ca912c 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -5732,77 +5732,7 @@  bpf_core_find_cands(struct bpf_object *obj, const struct btf *local_btf, __u32 l
 int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id,
 			      const struct btf *targ_btf, __u32 targ_id)
 {
-	const struct btf_type *local_type, *targ_type;
-	int depth = 32; /* max recursion depth */
-
-	/* caller made sure that names match (ignoring flavor suffix) */
-	local_type = btf__type_by_id(local_btf, local_id);
-	targ_type = btf__type_by_id(targ_btf, targ_id);
-	if (!btf_kind_core_compat(local_type, targ_type))
-		return 0;
-
-recur:
-	depth--;
-	if (depth < 0)
-		return -EINVAL;
-
-	local_type = skip_mods_and_typedefs(local_btf, local_id, &local_id);
-	targ_type = skip_mods_and_typedefs(targ_btf, targ_id, &targ_id);
-	if (!local_type || !targ_type)
-		return -EINVAL;
-
-	if (!btf_kind_core_compat(local_type, targ_type))
-		return 0;
-
-	switch (btf_kind(local_type)) {
-	case BTF_KIND_UNKN:
-	case BTF_KIND_STRUCT:
-	case BTF_KIND_UNION:
-	case BTF_KIND_ENUM:
-	case BTF_KIND_ENUM64:
-	case BTF_KIND_FWD:
-		return 1;
-	case BTF_KIND_INT:
-		/* just reject deprecated bitfield-like integers; all other
-		 * integers are by default compatible between each other
-		 */
-		return btf_int_offset(local_type) == 0 && btf_int_offset(targ_type) == 0;
-	case BTF_KIND_PTR:
-		local_id = local_type->type;
-		targ_id = targ_type->type;
-		goto recur;
-	case BTF_KIND_ARRAY:
-		local_id = btf_array(local_type)->type;
-		targ_id = btf_array(targ_type)->type;
-		goto recur;
-	case BTF_KIND_FUNC_PROTO: {
-		struct btf_param *local_p = btf_params(local_type);
-		struct btf_param *targ_p = btf_params(targ_type);
-		__u16 local_vlen = btf_vlen(local_type);
-		__u16 targ_vlen = btf_vlen(targ_type);
-		int i, err;
-
-		if (local_vlen != targ_vlen)
-			return 0;
-
-		for (i = 0; i < local_vlen; i++, local_p++, targ_p++) {
-			skip_mods_and_typedefs(local_btf, local_p->type, &local_id);
-			skip_mods_and_typedefs(targ_btf, targ_p->type, &targ_id);
-			err = bpf_core_types_are_compat(local_btf, local_id, targ_btf, targ_id);
-			if (err <= 0)
-				return err;
-		}
-
-		/* tail recurse for return type check */
-		skip_mods_and_typedefs(local_btf, local_type->type, &local_id);
-		skip_mods_and_typedefs(targ_btf, targ_type->type, &targ_id);
-		goto recur;
-	}
-	default:
-		pr_warn("unexpected kind %s relocated, local [%d], target [%d]\n",
-			btf_kind_str(local_type), local_id, targ_id);
-		return 0;
-	}
+	return bpf_core_types_are_compat_recur(local_btf, local_id, targ_btf, targ_id, INT_MAX);
 }
 
 static size_t bpf_core_hash_fn(const void *key, void *ctx)
diff --git a/tools/lib/bpf/relo_core.c b/tools/lib/bpf/relo_core.c
index 6ad3c3..e54370 100644
--- a/tools/lib/bpf/relo_core.c
+++ b/tools/lib/bpf/relo_core.c
@@ -141,6 +141,84 @@  static bool core_relo_is_enumval_based(enum bpf_core_relo_kind kind)
 	}
 }
 
+int bpf_core_types_are_compat_recur(const struct btf *local_btf, __u32 local_id,
+				    const struct btf *targ_btf, __u32 targ_id, int level)
+{
+	const struct btf_type *local_type, *targ_type;
+	int depth = 32; /* max recursion depth */
+
+	/* caller made sure that names match (ignoring flavor suffix) */
+	local_type = btf_type_by_id(local_btf, local_id);
+	targ_type = btf_type_by_id(targ_btf, targ_id);
+	if (!btf_kind_core_compat(local_type, targ_type))
+		return 0;
+
+recur:
+	depth--;
+	if (depth < 0)
+		return -EINVAL;
+
+	local_type = skip_mods_and_typedefs(local_btf, local_id, &local_id);
+	targ_type = skip_mods_and_typedefs(targ_btf, targ_id, &targ_id);
+	if (!local_type || !targ_type)
+		return -EINVAL;
+
+	if (!btf_kind_core_compat(local_type, targ_type))
+		return 0;
+
+	switch (btf_kind(local_type)) {
+	case BTF_KIND_UNKN:
+	case BTF_KIND_STRUCT:
+	case BTF_KIND_UNION:
+	case BTF_KIND_ENUM:
+	case BTF_KIND_FWD:
+	case BTF_KIND_ENUM64:
+		return 1;
+	case BTF_KIND_INT:
+		/* just reject deprecated bitfield-like integers; all other
+		 * integers are by default compatible between each other
+		 */
+		return btf_int_offset(local_type) == 0 && btf_int_offset(targ_type) == 0;
+	case BTF_KIND_PTR:
+		local_id = local_type->type;
+		targ_id = targ_type->type;
+		goto recur;
+	case BTF_KIND_ARRAY:
+		local_id = btf_array(local_type)->type;
+		targ_id = btf_array(targ_type)->type;
+		goto recur;
+	case BTF_KIND_FUNC_PROTO: {
+		struct btf_param *local_p = btf_params(local_type);
+		struct btf_param *targ_p = btf_params(targ_type);
+		__u16 local_vlen = btf_vlen(local_type);
+		__u16 targ_vlen = btf_vlen(targ_type);
+		int i, err;
+
+		if (local_vlen != targ_vlen)
+			return 0;
+
+		for (i = 0; i < local_vlen; i++, local_p++, targ_p++) {
+			if (level <= 0)
+				return -EINVAL;
+
+			skip_mods_and_typedefs(local_btf, local_p->type, &local_id);
+			skip_mods_and_typedefs(targ_btf, targ_p->type, &targ_id);
+			err = bpf_core_types_are_compat_recur(local_btf, local_id, targ_btf,
+							      targ_id, level - 1);
+			if (err <= 0)
+				return err;
+		}
+
+		/* tail recurse for return type check */
+		skip_mods_and_typedefs(local_btf, local_type->type, &local_id);
+		skip_mods_and_typedefs(targ_btf, targ_type->type, &targ_id);
+		goto recur;
+	}
+	default:
+		return 0;
+	}
+}
+
 /*
  * Turn bpf_core_relo into a low- and high-level spec representation,
  * validating correctness along the way, as well as calculating resulting
diff --git a/tools/lib/bpf/relo_core.h b/tools/lib/bpf/relo_core.h
index 7df0da0..b8998f 100644
--- a/tools/lib/bpf/relo_core.h
+++ b/tools/lib/bpf/relo_core.h
@@ -68,6 +68,8 @@  struct bpf_core_relo_res {
 	__u32 new_type_id;
 };
 
+int bpf_core_types_are_compat_recur(const struct btf *local_btf, __u32 local_id,
+				    const struct btf *targ_btf, __u32 targ_id, int level);
 int bpf_core_types_are_compat(const struct btf *local_btf, __u32 local_id,
 			      const struct btf *targ_btf, __u32 targ_id);