KUnit support is not consistently present across distributions, some
include it in their stock kernels, while others do not.
While both KUNIT and KUNIT_SUPPRESS_BACKTRACE can be considered debug
features, the fact that some distros ship with KUnit enabled means it's
important to minimize the runtime impact of this patch.
To that end, this patch introduces a counter for the number of
suppressed symbols and skips execution of __kunit_is_suppressed_warning()
entirely when no symbols are currently being suppressed.

Signed-off-by: Alessandro Carminati <acarm...@redhat.com>
---
 include/asm-generic/bug.h | 21 ++++++++++++++-------
 include/kunit/bug.h       |  1 +
 lib/kunit/bug.c           |  4 ++++
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 3cc8cb100ccd..c5587820bd8c 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -62,7 +62,8 @@ struct bug_entry {
  */
 #ifndef HAVE_ARCH_BUG
 #define BUG() do { \
-       if (!KUNIT_IS_SUPPRESSED_WARNING(__func__)) {                   \
+       if (suppressed_symbols_cnt &&                                   \
+           !KUNIT_IS_SUPPRESSED_WARNING(__func__)) {                   \
                printk("BUG: failure at %s:%d/%s()!\n", __FILE__,       \
                        __LINE__, __func__);                            \
                barrier_before_unreachable();                           \
@@ -99,7 +100,8 @@ extern __printf(1, 2) void __warn_printk(const char *fmt, 
...);
 #ifndef __WARN_FLAGS
 #define __WARN()               __WARN_printf(TAINT_WARN, NULL)
 #define __WARN_printf(taint, arg...) do {                              \
-               if (!KUNIT_IS_SUPPRESSED_WARNING(__func__)) {           \
+               if (suppressed_symbols_cnt &&                           \
+                   !KUNIT_IS_SUPPRESSED_WARNING(__func__)) {           \
                        instrumentation_begin();                        \
                        warn_slowpath_fmt(__FILE__, __LINE__, taint, arg);\
                        instrumentation_end();                          \
@@ -108,7 +110,8 @@ extern __printf(1, 2) void __warn_printk(const char *fmt, 
...);
 #else
 #define __WARN()               __WARN_FLAGS(BUGFLAG_TAINT(TAINT_WARN))
 #define __WARN_printf(taint, arg...) do {                              \
-               if (!KUNIT_IS_SUPPRESSED_WARNING(__func__)) {           \
+               if (suppressed_symbols_cnt &&                           \
+                   !KUNIT_IS_SUPPRESSED_WARNING(__func__)) {           \
                        instrumentation_begin();                        \
                        __warn_printk(arg);                             \
                        __WARN_FLAGS(BUGFLAG_NO_CUT_HERE |              \
@@ -118,7 +121,8 @@ extern __printf(1, 2) void __warn_printk(const char *fmt, 
...);
        } while (0)
 #define WARN_ON_ONCE(condition) ({                             \
        int __ret_warn_on = !!(condition);                      \
-       if (unlikely(__ret_warn_on) && !KUNIT_IS_SUPPRESSED_WARNING(__func__))  
\
+       if (unlikely(__ret_warn_on) && suppressed_symbols_cnt &&\
+           !KUNIT_IS_SUPPRESSED_WARNING(__func__))             \
                __WARN_FLAGS(BUGFLAG_ONCE |                     \
                             BUGFLAG_TAINT(TAINT_WARN));        \
        unlikely(__ret_warn_on);                                \
@@ -130,7 +134,8 @@ extern __printf(1, 2) void __warn_printk(const char *fmt, 
...);
 #ifndef WARN_ON
 #define WARN_ON(condition) ({                                          \
        int __ret_warn_on = !!(condition);                              \
-       if (unlikely(__ret_warn_on) && !KUNIT_IS_SUPPRESSED_WARNING(__func__))  
\
+       if (unlikely(__ret_warn_on) && suppressed_symbols_cnt &&        \
+           !KUNIT_IS_SUPPRESSED_WARNING(__func__))                     \
                __WARN();                                               \
        unlikely(__ret_warn_on);                                        \
 })
@@ -147,7 +152,8 @@ extern __printf(1, 2) void __warn_printk(const char *fmt, 
...);
 
 #define WARN_TAINT(condition, taint, format...) ({                     \
        int __ret_warn_on = !!(condition);                              \
-       if (unlikely(__ret_warn_on) && !KUNIT_IS_SUPPRESSED_WARNING(__func__))  
\
+       if (unlikely(__ret_warn_on) && suppressed_symbols_cnt &&        \
+           !KUNIT_IS_SUPPRESSED_WARNING(__func__))                     \
                __WARN_printf(taint, format);                           \
        unlikely(__ret_warn_on);                                        \
 })
@@ -166,7 +172,8 @@ extern __printf(1, 2) void __warn_printk(const char *fmt, 
...);
 #else /* !CONFIG_BUG */
 #ifndef HAVE_ARCH_BUG
 #define BUG() do {             \
-       if (!KUNIT_IS_SUPPRESSED_WARNING(__func__)) {                   \
+       if (suppressed_symbols_cnt &&                                   \
+           !KUNIT_IS_SUPPRESSED_WARNING(__func__)) {                   \
                do {} while (1);                                        \
                unreachable();                                          \
        }                                                               \
diff --git a/include/kunit/bug.h b/include/kunit/bug.h
index 9a4eff2897e9..3256e3f2c165 100644
--- a/include/kunit/bug.h
+++ b/include/kunit/bug.h
@@ -23,6 +23,7 @@ struct __suppressed_warning {
        const char *function;
        int counter;
 };
+extern int suppressed_symbols_cnt;
 
 void __kunit_start_suppress_warning(struct __suppressed_warning *warning);
 void __kunit_end_suppress_warning(struct __suppressed_warning *warning);
diff --git a/lib/kunit/bug.c b/lib/kunit/bug.c
index 4da9ae478f25..5beaee1049eb 100644
--- a/lib/kunit/bug.c
+++ b/lib/kunit/bug.c
@@ -11,15 +11,19 @@
 #include <linux/list.h>
 
 static LIST_HEAD(suppressed_warnings);
+int suppressed_symbols_cnt = 0;
+EXPORT_SYMBOL_GPL(suppressed_symbols_cnt);
 
 void __kunit_start_suppress_warning(struct __suppressed_warning *warning)
 {
+       suppressed_symbols_cnt++;
        list_add(&warning->node, &suppressed_warnings);
 }
 EXPORT_SYMBOL_GPL(__kunit_start_suppress_warning);
 
 void __kunit_end_suppress_warning(struct __suppressed_warning *warning)
 {
+       suppressed_symbols_cnt--;
        list_del(&warning->node);
 }
 EXPORT_SYMBOL_GPL(__kunit_end_suppress_warning);
-- 
2.34.1


Reply via email to