objtool: Increase per-function WARN_FUNC() rate limit
authorJosh Poimboeuf <jpoimboe@kernel.org>
Fri, 14 Mar 2025 19:29:03 +0000 (12:29 -0700)
committerPeter Zijlstra <peterz@infradead.org>
Mon, 17 Mar 2025 10:36:00 +0000 (11:36 +0100)
Increase the per-function WARN_FUNC() rate limit from 1 to 2.  If the
number of warnings for a given function goes beyond 2, print "skipping
duplicate warning(s)".  This helps root out additional warnings in a
function that might be hiding behind the first one.

Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/aec318d66c037a51c9f376d6fb0e8ff32812a037.1741975349.git.jpoimboe@kernel.org
tools/objtool/check.c
tools/objtool/include/objtool/elf.h
tools/objtool/include/objtool/warn.h

index d6af5385baf6147df179187d75c2143dbd0c908c..2f64e46fe02d39ae8fe2d1ad1629004300964a0f 100644 (file)
@@ -4547,7 +4547,7 @@ static int disas_warned_funcs(struct objtool_file *file)
        char *funcs = NULL, *tmp;
 
        for_each_sym(file, sym) {
-               if (sym->warned) {
+               if (sym->warnings) {
                        if (!funcs) {
                                funcs = malloc(strlen(sym->name) + 1);
                                strcpy(funcs, sym->name);
index d7e815c2fd1567bdd86fdbb78e26b5ab68238398..223ac1c24b90670852e66c2075ef66fcec5f717a 100644 (file)
@@ -65,10 +65,10 @@ struct symbol {
        u8 return_thunk      : 1;
        u8 fentry            : 1;
        u8 profiling_func    : 1;
-       u8 warned            : 1;
        u8 embedded_insn     : 1;
        u8 local_label       : 1;
        u8 frame_pointer     : 1;
+       u8 warnings          : 2;
        struct list_head pv_target;
        struct reloc *relocs;
 };
index ac04d3fe4dd9c17e1197f5b07b4fa71e8a72e3bb..6180288927fd7b5fe12cd5671b90b3371cf5ca2e 100644 (file)
@@ -53,14 +53,22 @@ static inline char *offstr(struct section *sec, unsigned long offset)
        free(_str);                                     \
 })
 
+#define WARN_LIMIT 2
+
 #define WARN_INSN(insn, format, ...)                                   \
 ({                                                                     \
        struct instruction *_insn = (insn);                             \
-       if (!_insn->sym || !_insn->sym->warned)                         \
+       BUILD_BUG_ON(WARN_LIMIT > 2);                                   \
+       if (!_insn->sym || _insn->sym->warnings < WARN_LIMIT) {         \
                WARN_FUNC(format, _insn->sec, _insn->offset,            \
                          ##__VA_ARGS__);                               \
-       if (_insn->sym)                                                 \
-               _insn->sym->warned = 1;                                 \
+               if (_insn->sym)                                         \
+                       _insn->sym->warnings++;                         \
+       } else if (_insn->sym && _insn->sym->warnings == WARN_LIMIT) {  \
+               WARN_FUNC("skipping duplicate warning(s)",              \
+                         _insn->sec, _insn->offset);                   \
+               _insn->sym->warnings++;                                 \
+       }                                                               \
 })
 
 #define BT_INSN(insn, format, ...)                             \