diff mbox series

[v2,1/2] tools/resolve_btfids: Add --fatal-warnings option

Message ID 20241126-resolve_btfids-v2-1-288c37cb89ee@weissschuh.net (mailing list archive)
State New
Headers show
Series kbuild: propagate CONFIG_WERROR to resolve_btfids | expand

Commit Message

Thomas Weißschuh Nov. 26, 2024, 9:17 p.m. UTC
Currently warnings emitted by resolve_btfids are buried in the build log
and are slipping into mainline frequently.
Add an option to elevate warnings to hard errors so the CI bots can
catch any new warnings.

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
Acked-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/bpf/resolve_btfids/main.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

Comments

Andrii Nakryiko Dec. 3, 2024, 10:31 p.m. UTC | #1
On Tue, Nov 26, 2024 at 1:17 PM Thomas Weißschuh <linux@weissschuh.net> wrote:
>
> Currently warnings emitted by resolve_btfids are buried in the build log
> and are slipping into mainline frequently.
> Add an option to elevate warnings to hard errors so the CI bots can
> catch any new warnings.
>
> Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> Acked-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/bpf/resolve_btfids/main.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> index bd9f960bce3d5b74dc34159b35af1e0b33524d2d..571d29d2da97fea75e5f9c544a95b9ac65f9e579 100644
> --- a/tools/bpf/resolve_btfids/main.c
> +++ b/tools/bpf/resolve_btfids/main.c
> @@ -141,6 +141,7 @@ struct object {
>  };
>
>  static int verbose;
> +static int warnings;
>
>  static int eprintf(int level, int var, const char *fmt, ...)
>  {
> @@ -604,6 +605,7 @@ static int symbols_resolve(struct object *obj)
>                         if (id->id) {
>                                 pr_info("WARN: multiple IDs found for '%s': %d, %d - using %d\n",
>                                         str, id->id, type_id, id->id);
> +                               warnings++;
>                         } else {
>                                 id->id = type_id;
>                                 (*nr)--;
> @@ -625,8 +627,10 @@ static int id_patch(struct object *obj, struct btf_id *id)
>         int i;
>
>         /* For set, set8, id->id may be 0 */
> -       if (!id->id && !id->is_set && !id->is_set8)
> +       if (!id->id && !id->is_set && !id->is_set8) {
>                 pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
> +               warnings++;
> +       }
>
>         for (i = 0; i < id->addr_cnt; i++) {
>                 unsigned long addr = id->addr[i];
> @@ -782,6 +786,7 @@ int main(int argc, const char **argv)
>                 .funcs    = RB_ROOT,
>                 .sets     = RB_ROOT,
>         };
> +       bool fatal_warnings = false;
>         struct option btfid_options[] = {
>                 OPT_INCR('v', "verbose", &verbose,
>                          "be more verbose (show errors, etc)"),
> @@ -789,6 +794,8 @@ int main(int argc, const char **argv)
>                            "BTF data"),
>                 OPT_STRING('b', "btf_base", &obj.base_btf_path, "file",
>                            "path of file providing base BTF"),
> +               OPT_BOOLEAN(0, "fatal-warnings", &fatal_warnings,
> +                           "turn warnings into errors"),

We are mixing naming styles here: we have "btf_base" with underscore
separator, and you are adding "fatal-warnings" with dash separator. I
personally like dashes, but whichever way we should stay consistent.
So let's fix it, otherwise it looks a bit sloppy.

Please also use [PATCH bpf-next v3] subject prefix to make it explicit
that this should go through bpf-next tree.

pw-bot: cr

>                 OPT_END()
>         };
>         int err = -1;
> @@ -823,7 +830,8 @@ int main(int argc, const char **argv)
>         if (symbols_patch(&obj))
>                 goto out;
>
> -       err = 0;
> +       if (!(fatal_warnings && warnings))
> +               err = 0;

nit: just

if (!fatal_warnings)
    err = 0;

?

>  out:
>         if (obj.efile.elf) {
>                 elf_end(obj.efile.elf);
>
> --
> 2.47.1
>
Thomas Weißschuh Dec. 3, 2024, 11:09 p.m. UTC | #2
On 2024-12-03 14:31:01-0800, Andrii Nakryiko wrote:
> On Tue, Nov 26, 2024 at 1:17 PM Thomas Weißschuh <linux@weissschuh.net> wrote:
> >
> > Currently warnings emitted by resolve_btfids are buried in the build log
> > and are slipping into mainline frequently.
> > Add an option to elevate warnings to hard errors so the CI bots can
> > catch any new warnings.
> >
> > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > Acked-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> >  tools/bpf/resolve_btfids/main.c | 12 ++++++++++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> > index bd9f960bce3d5b74dc34159b35af1e0b33524d2d..571d29d2da97fea75e5f9c544a95b9ac65f9e579 100644
> > --- a/tools/bpf/resolve_btfids/main.c
> > +++ b/tools/bpf/resolve_btfids/main.c
> > @@ -141,6 +141,7 @@ struct object {
> >  };
> >
> >  static int verbose;
> > +static int warnings;
> >
> >  static int eprintf(int level, int var, const char *fmt, ...)
> >  {
> > @@ -604,6 +605,7 @@ static int symbols_resolve(struct object *obj)
> >                         if (id->id) {
> >                                 pr_info("WARN: multiple IDs found for '%s': %d, %d - using %d\n",
> >                                         str, id->id, type_id, id->id);
> > +                               warnings++;
> >                         } else {
> >                                 id->id = type_id;
> >                                 (*nr)--;
> > @@ -625,8 +627,10 @@ static int id_patch(struct object *obj, struct btf_id *id)
> >         int i;
> >
> >         /* For set, set8, id->id may be 0 */
> > -       if (!id->id && !id->is_set && !id->is_set8)
> > +       if (!id->id && !id->is_set && !id->is_set8) {
> >                 pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
> > +               warnings++;
> > +       }
> >
> >         for (i = 0; i < id->addr_cnt; i++) {
> >                 unsigned long addr = id->addr[i];
> > @@ -782,6 +786,7 @@ int main(int argc, const char **argv)
> >                 .funcs    = RB_ROOT,
> >                 .sets     = RB_ROOT,
> >         };
> > +       bool fatal_warnings = false;
> >         struct option btfid_options[] = {
> >                 OPT_INCR('v', "verbose", &verbose,
> >                          "be more verbose (show errors, etc)"),
> > @@ -789,6 +794,8 @@ int main(int argc, const char **argv)
> >                            "BTF data"),
> >                 OPT_STRING('b', "btf_base", &obj.base_btf_path, "file",
> >                            "path of file providing base BTF"),
> > +               OPT_BOOLEAN(0, "fatal-warnings", &fatal_warnings,
> > +                           "turn warnings into errors"),
> 
> We are mixing naming styles here: we have "btf_base" with underscore
> separator, and you are adding "fatal-warnings" with dash separator. I
> personally like dashes, but whichever way we should stay consistent.
> So let's fix it, otherwise it looks a bit sloppy.

Ack.

> 
> Please also use [PATCH bpf-next v3] subject prefix to make it explicit
> that this should go through bpf-next tree.

Ack.

> 
> pw-bot: cr
> 
> >                 OPT_END()
> >         };
> >         int err = -1;
> > @@ -823,7 +830,8 @@ int main(int argc, const char **argv)
> >         if (symbols_patch(&obj))
> >                 goto out;
> >
> > -       err = 0;
> > +       if (!(fatal_warnings && warnings))
> > +               err = 0;
> 
> nit: just
> 
> if (!fatal_warnings)
>     err = 0;
> 
> ?

This seems wrong. Now the actual warning counter is never evaluated.
And --fatal_warnings will always lead to an error exit code.

> >  out:
> >         if (obj.efile.elf) {
> >                 elf_end(obj.efile.elf);
> >
> > --
> > 2.47.1
> >
Andrii Nakryiko Dec. 4, 2024, 2:06 a.m. UTC | #3
On Tue, Dec 3, 2024 at 3:09 PM Thomas Weißschuh <linux@weissschuh.net> wrote:
>
> On 2024-12-03 14:31:01-0800, Andrii Nakryiko wrote:
> > On Tue, Nov 26, 2024 at 1:17 PM Thomas Weißschuh <linux@weissschuh.net> wrote:
> > >
> > > Currently warnings emitted by resolve_btfids are buried in the build log
> > > and are slipping into mainline frequently.
> > > Add an option to elevate warnings to hard errors so the CI bots can
> > > catch any new warnings.
> > >
> > > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > > Acked-by: Jiri Olsa <jolsa@kernel.org>
> > > ---
> > >  tools/bpf/resolve_btfids/main.c | 12 ++++++++++--
> > >  1 file changed, 10 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> > > index bd9f960bce3d5b74dc34159b35af1e0b33524d2d..571d29d2da97fea75e5f9c544a95b9ac65f9e579 100644
> > > --- a/tools/bpf/resolve_btfids/main.c
> > > +++ b/tools/bpf/resolve_btfids/main.c
> > > @@ -141,6 +141,7 @@ struct object {
> > >  };
> > >
> > >  static int verbose;
> > > +static int warnings;
> > >
> > >  static int eprintf(int level, int var, const char *fmt, ...)
> > >  {
> > > @@ -604,6 +605,7 @@ static int symbols_resolve(struct object *obj)
> > >                         if (id->id) {
> > >                                 pr_info("WARN: multiple IDs found for '%s': %d, %d - using %d\n",
> > >                                         str, id->id, type_id, id->id);
> > > +                               warnings++;
> > >                         } else {
> > >                                 id->id = type_id;
> > >                                 (*nr)--;
> > > @@ -625,8 +627,10 @@ static int id_patch(struct object *obj, struct btf_id *id)
> > >         int i;
> > >
> > >         /* For set, set8, id->id may be 0 */
> > > -       if (!id->id && !id->is_set && !id->is_set8)
> > > +       if (!id->id && !id->is_set && !id->is_set8) {
> > >                 pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
> > > +               warnings++;
> > > +       }
> > >
> > >         for (i = 0; i < id->addr_cnt; i++) {
> > >                 unsigned long addr = id->addr[i];
> > > @@ -782,6 +786,7 @@ int main(int argc, const char **argv)
> > >                 .funcs    = RB_ROOT,
> > >                 .sets     = RB_ROOT,
> > >         };
> > > +       bool fatal_warnings = false;
> > >         struct option btfid_options[] = {
> > >                 OPT_INCR('v', "verbose", &verbose,
> > >                          "be more verbose (show errors, etc)"),
> > > @@ -789,6 +794,8 @@ int main(int argc, const char **argv)
> > >                            "BTF data"),
> > >                 OPT_STRING('b', "btf_base", &obj.base_btf_path, "file",
> > >                            "path of file providing base BTF"),
> > > +               OPT_BOOLEAN(0, "fatal-warnings", &fatal_warnings,
> > > +                           "turn warnings into errors"),
> >
> > We are mixing naming styles here: we have "btf_base" with underscore
> > separator, and you are adding "fatal-warnings" with dash separator. I
> > personally like dashes, but whichever way we should stay consistent.
> > So let's fix it, otherwise it looks a bit sloppy.
>
> Ack.
>
> >
> > Please also use [PATCH bpf-next v3] subject prefix to make it explicit
> > that this should go through bpf-next tree.
>
> Ack.
>
> >
> > pw-bot: cr
> >
> > >                 OPT_END()
> > >         };
> > >         int err = -1;
> > > @@ -823,7 +830,8 @@ int main(int argc, const char **argv)
> > >         if (symbols_patch(&obj))
> > >                 goto out;
> > >
> > > -       err = 0;
> > > +       if (!(fatal_warnings && warnings))
> > > +               err = 0;
> >
> > nit: just
> >
> > if (!fatal_warnings)
> >     err = 0;
> >
> > ?
>
> This seems wrong. Now the actual warning counter is never evaluated.
> And --fatal_warnings will always lead to an error exit code.

Ah, I missed that you are using default -1 value here. I wonder if we
should make it a bit more explicit?

if (fatal_warnings)
    err = warnings ? -1 : 0;
else
    err = 0;

Something like that?

>
> > >  out:
> > >         if (obj.efile.elf) {
> > >                 elf_end(obj.efile.elf);
> > >
> > > --
> > > 2.47.1
> > >
Thomas Weißschuh Dec. 4, 2024, 6:19 a.m. UTC | #4
On 2024-12-03 18:06:26-0800, Andrii Nakryiko wrote:
> On Tue, Dec 3, 2024 at 3:09 PM Thomas Weißschuh <linux@weissschuh.net> wrote:
> >
> > On 2024-12-03 14:31:01-0800, Andrii Nakryiko wrote:
> > > On Tue, Nov 26, 2024 at 1:17 PM Thomas Weißschuh <linux@weissschuh.net> wrote:
> > > >
> > > > Currently warnings emitted by resolve_btfids are buried in the build log
> > > > and are slipping into mainline frequently.
> > > > Add an option to elevate warnings to hard errors so the CI bots can
> > > > catch any new warnings.
> > > >
> > > > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > > > Acked-by: Jiri Olsa <jolsa@kernel.org>
> > > > ---
> > > >  tools/bpf/resolve_btfids/main.c | 12 ++++++++++--
> > > >  1 file changed, 10 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> > > > index bd9f960bce3d5b74dc34159b35af1e0b33524d2d..571d29d2da97fea75e5f9c544a95b9ac65f9e579 100644
> > > > --- a/tools/bpf/resolve_btfids/main.c
> > > > +++ b/tools/bpf/resolve_btfids/main.c
> > > > @@ -141,6 +141,7 @@ struct object {
> > > >  };
> > > >
> > > >  static int verbose;
> > > > +static int warnings;
> > > >
> > > >  static int eprintf(int level, int var, const char *fmt, ...)
> > > >  {
> > > > @@ -604,6 +605,7 @@ static int symbols_resolve(struct object *obj)
> > > >                         if (id->id) {
> > > >                                 pr_info("WARN: multiple IDs found for '%s': %d, %d - using %d\n",
> > > >                                         str, id->id, type_id, id->id);
> > > > +                               warnings++;
> > > >                         } else {
> > > >                                 id->id = type_id;
> > > >                                 (*nr)--;
> > > > @@ -625,8 +627,10 @@ static int id_patch(struct object *obj, struct btf_id *id)
> > > >         int i;
> > > >
> > > >         /* For set, set8, id->id may be 0 */
> > > > -       if (!id->id && !id->is_set && !id->is_set8)
> > > > +       if (!id->id && !id->is_set && !id->is_set8) {
> > > >                 pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
> > > > +               warnings++;
> > > > +       }
> > > >
> > > >         for (i = 0; i < id->addr_cnt; i++) {
> > > >                 unsigned long addr = id->addr[i];
> > > > @@ -782,6 +786,7 @@ int main(int argc, const char **argv)
> > > >                 .funcs    = RB_ROOT,
> > > >                 .sets     = RB_ROOT,
> > > >         };
> > > > +       bool fatal_warnings = false;
> > > >         struct option btfid_options[] = {
> > > >                 OPT_INCR('v', "verbose", &verbose,
> > > >                          "be more verbose (show errors, etc)"),
> > > > @@ -789,6 +794,8 @@ int main(int argc, const char **argv)
> > > >                            "BTF data"),
> > > >                 OPT_STRING('b', "btf_base", &obj.base_btf_path, "file",
> > > >                            "path of file providing base BTF"),
> > > > +               OPT_BOOLEAN(0, "fatal-warnings", &fatal_warnings,
> > > > +                           "turn warnings into errors"),
> > >
> > > We are mixing naming styles here: we have "btf_base" with underscore
> > > separator, and you are adding "fatal-warnings" with dash separator. I
> > > personally like dashes, but whichever way we should stay consistent.
> > > So let's fix it, otherwise it looks a bit sloppy.
> >
> > Ack.
> >
> > >
> > > Please also use [PATCH bpf-next v3] subject prefix to make it explicit
> > > that this should go through bpf-next tree.
> >
> > Ack.
> >
> > >
> > > pw-bot: cr
> > >
> > > >                 OPT_END()
> > > >         };
> > > >         int err = -1;
> > > > @@ -823,7 +830,8 @@ int main(int argc, const char **argv)
> > > >         if (symbols_patch(&obj))
> > > >                 goto out;
> > > >
> > > > -       err = 0;
> > > > +       if (!(fatal_warnings && warnings))
> > > > +               err = 0;
> > >
> > > nit: just
> > >
> > > if (!fatal_warnings)
> > >     err = 0;
> > >
> > > ?
> >
> > This seems wrong. Now the actual warning counter is never evaluated.
> > And --fatal_warnings will always lead to an error exit code.
> 
> Ah, I missed that you are using default -1 value here. I wonder if we
> should make it a bit more explicit?
> 
> if (fatal_warnings)
>     err = warnings ? -1 : 0;
> else
>     err = 0;
> 
> Something like that?

The existing code was the same. Also the rest of the function
relies on this. IMO the pattern is clear when looking at the resulting
code and not the diff.
But if you prefer I can change it of course.

> > > >  out:
> > > >         if (obj.efile.elf) {
> > > >                 elf_end(obj.efile.elf);
> > > >
> > > > --
> > > > 2.47.1
> > > >
Andrii Nakryiko Dec. 4, 2024, 5:57 p.m. UTC | #5
On Tue, Dec 3, 2024 at 10:19 PM Thomas Weißschuh <linux@weissschuh.net> wrote:
>
> On 2024-12-03 18:06:26-0800, Andrii Nakryiko wrote:
> > On Tue, Dec 3, 2024 at 3:09 PM Thomas Weißschuh <linux@weissschuh.net> wrote:
> > >
> > > On 2024-12-03 14:31:01-0800, Andrii Nakryiko wrote:
> > > > On Tue, Nov 26, 2024 at 1:17 PM Thomas Weißschuh <linux@weissschuh.net> wrote:
> > > > >
> > > > > Currently warnings emitted by resolve_btfids are buried in the build log
> > > > > and are slipping into mainline frequently.
> > > > > Add an option to elevate warnings to hard errors so the CI bots can
> > > > > catch any new warnings.
> > > > >
> > > > > Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
> > > > > Acked-by: Jiri Olsa <jolsa@kernel.org>
> > > > > ---
> > > > >  tools/bpf/resolve_btfids/main.c | 12 ++++++++++--
> > > > >  1 file changed, 10 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
> > > > > index bd9f960bce3d5b74dc34159b35af1e0b33524d2d..571d29d2da97fea75e5f9c544a95b9ac65f9e579 100644
> > > > > --- a/tools/bpf/resolve_btfids/main.c
> > > > > +++ b/tools/bpf/resolve_btfids/main.c
> > > > > @@ -141,6 +141,7 @@ struct object {
> > > > >  };
> > > > >
> > > > >  static int verbose;
> > > > > +static int warnings;
> > > > >
> > > > >  static int eprintf(int level, int var, const char *fmt, ...)
> > > > >  {
> > > > > @@ -604,6 +605,7 @@ static int symbols_resolve(struct object *obj)
> > > > >                         if (id->id) {
> > > > >                                 pr_info("WARN: multiple IDs found for '%s': %d, %d - using %d\n",
> > > > >                                         str, id->id, type_id, id->id);
> > > > > +                               warnings++;
> > > > >                         } else {
> > > > >                                 id->id = type_id;
> > > > >                                 (*nr)--;
> > > > > @@ -625,8 +627,10 @@ static int id_patch(struct object *obj, struct btf_id *id)
> > > > >         int i;
> > > > >
> > > > >         /* For set, set8, id->id may be 0 */
> > > > > -       if (!id->id && !id->is_set && !id->is_set8)
> > > > > +       if (!id->id && !id->is_set && !id->is_set8) {
> > > > >                 pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
> > > > > +               warnings++;
> > > > > +       }
> > > > >
> > > > >         for (i = 0; i < id->addr_cnt; i++) {
> > > > >                 unsigned long addr = id->addr[i];
> > > > > @@ -782,6 +786,7 @@ int main(int argc, const char **argv)
> > > > >                 .funcs    = RB_ROOT,
> > > > >                 .sets     = RB_ROOT,
> > > > >         };
> > > > > +       bool fatal_warnings = false;
> > > > >         struct option btfid_options[] = {
> > > > >                 OPT_INCR('v', "verbose", &verbose,
> > > > >                          "be more verbose (show errors, etc)"),
> > > > > @@ -789,6 +794,8 @@ int main(int argc, const char **argv)
> > > > >                            "BTF data"),
> > > > >                 OPT_STRING('b', "btf_base", &obj.base_btf_path, "file",
> > > > >                            "path of file providing base BTF"),
> > > > > +               OPT_BOOLEAN(0, "fatal-warnings", &fatal_warnings,
> > > > > +                           "turn warnings into errors"),
> > > >
> > > > We are mixing naming styles here: we have "btf_base" with underscore
> > > > separator, and you are adding "fatal-warnings" with dash separator. I
> > > > personally like dashes, but whichever way we should stay consistent.
> > > > So let's fix it, otherwise it looks a bit sloppy.
> > >
> > > Ack.
> > >
> > > >
> > > > Please also use [PATCH bpf-next v3] subject prefix to make it explicit
> > > > that this should go through bpf-next tree.
> > >
> > > Ack.
> > >
> > > >
> > > > pw-bot: cr
> > > >
> > > > >                 OPT_END()
> > > > >         };
> > > > >         int err = -1;
> > > > > @@ -823,7 +830,8 @@ int main(int argc, const char **argv)
> > > > >         if (symbols_patch(&obj))
> > > > >                 goto out;
> > > > >
> > > > > -       err = 0;
> > > > > +       if (!(fatal_warnings && warnings))
> > > > > +               err = 0;
> > > >
> > > > nit: just
> > > >
> > > > if (!fatal_warnings)
> > > >     err = 0;
> > > >
> > > > ?
> > >
> > > This seems wrong. Now the actual warning counter is never evaluated.
> > > And --fatal_warnings will always lead to an error exit code.
> >
> > Ah, I missed that you are using default -1 value here. I wonder if we
> > should make it a bit more explicit?
> >
> > if (fatal_warnings)
> >     err = warnings ? -1 : 0;
> > else
> >     err = 0;
> >
> > Something like that?
>
> The existing code was the same. Also the rest of the function
> relies on this. IMO the pattern is clear when looking at the resulting
> code and not the diff.
> But if you prefer I can change it of course.

That new condition breaks my brain, but luckily I don't have to look
at it often, so I don't care all that much. Feel free to leave it as
is.

>
> > > > >  out:
> > > > >         if (obj.efile.elf) {
> > > > >                 elf_end(obj.efile.elf);
> > > > >
> > > > > --
> > > > > 2.47.1
> > > > >
diff mbox series

Patch

diff --git a/tools/bpf/resolve_btfids/main.c b/tools/bpf/resolve_btfids/main.c
index bd9f960bce3d5b74dc34159b35af1e0b33524d2d..571d29d2da97fea75e5f9c544a95b9ac65f9e579 100644
--- a/tools/bpf/resolve_btfids/main.c
+++ b/tools/bpf/resolve_btfids/main.c
@@ -141,6 +141,7 @@  struct object {
 };
 
 static int verbose;
+static int warnings;
 
 static int eprintf(int level, int var, const char *fmt, ...)
 {
@@ -604,6 +605,7 @@  static int symbols_resolve(struct object *obj)
 			if (id->id) {
 				pr_info("WARN: multiple IDs found for '%s': %d, %d - using %d\n",
 					str, id->id, type_id, id->id);
+				warnings++;
 			} else {
 				id->id = type_id;
 				(*nr)--;
@@ -625,8 +627,10 @@  static int id_patch(struct object *obj, struct btf_id *id)
 	int i;
 
 	/* For set, set8, id->id may be 0 */
-	if (!id->id && !id->is_set && !id->is_set8)
+	if (!id->id && !id->is_set && !id->is_set8) {
 		pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id->name);
+		warnings++;
+	}
 
 	for (i = 0; i < id->addr_cnt; i++) {
 		unsigned long addr = id->addr[i];
@@ -782,6 +786,7 @@  int main(int argc, const char **argv)
 		.funcs    = RB_ROOT,
 		.sets     = RB_ROOT,
 	};
+	bool fatal_warnings = false;
 	struct option btfid_options[] = {
 		OPT_INCR('v', "verbose", &verbose,
 			 "be more verbose (show errors, etc)"),
@@ -789,6 +794,8 @@  int main(int argc, const char **argv)
 			   "BTF data"),
 		OPT_STRING('b', "btf_base", &obj.base_btf_path, "file",
 			   "path of file providing base BTF"),
+		OPT_BOOLEAN(0, "fatal-warnings", &fatal_warnings,
+			    "turn warnings into errors"),
 		OPT_END()
 	};
 	int err = -1;
@@ -823,7 +830,8 @@  int main(int argc, const char **argv)
 	if (symbols_patch(&obj))
 		goto out;
 
-	err = 0;
+	if (!(fatal_warnings && warnings))
+		err = 0;
 out:
 	if (obj.efile.elf) {
 		elf_end(obj.efile.elf);