]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
dynamic_debug: add support for print stack
authorYe Bin <yebin10@huawei.com>
Sat, 25 Oct 2025 08:00:03 +0000 (16:00 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 12 Nov 2025 18:00:16 +0000 (10:00 -0800)
In practical problem diagnosis, especially during the boot phase, it is
often desirable to know the call sequence.  However, currently, apart from
adding print statements and recompiling the kernel, there seems to be no
good alternative.  If dynamic_debug supported printing the call stack, it
would be very helpful for diagnosing issues.  This patch add support '+d'
for dump stack.

Link: https://lkml.kernel.org/r/20251025080003.312536-1-yebin@huaweicloud.com
Signed-off-by: Ye Bin <yebin10@huawei.com>
Cc: Jason Baron <jbaron@akamai.com>
Cc: Jim Cromie <jim.cromie@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Documentation/admin-guide/dynamic-debug-howto.rst
include/linux/dynamic_debug.h
lib/dynamic_debug.c

index 7c036590cd07c15565717146bbeb3f1aacf92430..095a63892257e43de7ecbc7c33125be39e0e5091 100644 (file)
@@ -223,12 +223,13 @@ The flags are::
   f    Include the function name
   s    Include the source file name
   l    Include line number
+  d    Include call trace
 
 For ``print_hex_dump_debug()`` and ``print_hex_dump_bytes()``, only
 the ``p`` flag has meaning, other flags are ignored.
 
-Note the regexp ``^[-+=][fslmpt_]+$`` matches a flags specification.
-To clear all flags at once, use ``=_`` or ``-fslmpt``.
+Note the regexp ``^[-+=][fslmptd_]+$`` matches a flags specification.
+To clear all flags at once, use ``=_`` or ``-fslmptd``.
 
 
 Debug messages during Boot Process
index ff44ec346162a164cbaf42c7df6f3894505d0654..05743900a116979b9fef0c49dcdcee1ab7575b88 100644 (file)
@@ -38,11 +38,12 @@ struct _ddebug {
 #define _DPRINTK_FLAGS_INCL_LINENO     (1<<3)
 #define _DPRINTK_FLAGS_INCL_TID                (1<<4)
 #define _DPRINTK_FLAGS_INCL_SOURCENAME (1<<5)
+#define _DPRINTK_FLAGS_INCL_STACK      (1<<6)
 
 #define _DPRINTK_FLAGS_INCL_ANY                \
        (_DPRINTK_FLAGS_INCL_MODNAME | _DPRINTK_FLAGS_INCL_FUNCNAME |\
         _DPRINTK_FLAGS_INCL_LINENO  | _DPRINTK_FLAGS_INCL_TID |\
-        _DPRINTK_FLAGS_INCL_SOURCENAME)
+        _DPRINTK_FLAGS_INCL_SOURCENAME | _DPRINTK_FLAGS_INCL_STACK)
 
 #if defined DEBUG
 #define _DPRINTK_FLAGS_DEFAULT _DPRINTK_FLAGS_PRINT
@@ -160,6 +161,12 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
                         const struct ib_device *ibdev,
                         const char *fmt, ...);
 
+#define __dynamic_dump_stack(desc)                             \
+{                                                              \
+       if (desc.flags & _DPRINTK_FLAGS_INCL_STACK)             \
+               dump_stack();                                   \
+}
+
 #define DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, cls, fmt)      \
        static struct _ddebug  __aligned(8)                     \
        __section("__dyndbg") name = {                          \
@@ -220,8 +227,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
  */
 #define __dynamic_func_call_cls(id, cls, fmt, func, ...) do {  \
        DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt);        \
-       if (DYNAMIC_DEBUG_BRANCH(id))                           \
+       if (DYNAMIC_DEBUG_BRANCH(id)) {                         \
                func(&id, ##__VA_ARGS__);                       \
+               __dynamic_dump_stack(id);                       \
+       }                                                       \
 } while (0)
 #define __dynamic_func_call(id, fmt, func, ...)                                \
        __dynamic_func_call_cls(id, _DPRINTK_CLASS_DFLT, fmt,           \
@@ -229,8 +238,10 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor,
 
 #define __dynamic_func_call_cls_no_desc(id, cls, fmt, func, ...) do {  \
        DEFINE_DYNAMIC_DEBUG_METADATA_CLS(id, cls, fmt);                \
-       if (DYNAMIC_DEBUG_BRANCH(id))                                   \
+       if (DYNAMIC_DEBUG_BRANCH(id)) {                                 \
                func(__VA_ARGS__);                                      \
+               __dynamic_dump_stack(id);                               \
+       }                                                               \
 } while (0)
 #define __dynamic_func_call_no_desc(id, fmt, func, ...)                        \
        __dynamic_func_call_cls_no_desc(id, _DPRINTK_CLASS_DFLT,        \
index 5a007952f7f24ede6bae7ef3c73b6cc0613215ca..7d7892e57a012a4b15aa8fddc3a2e1986010b9e4 100644 (file)
@@ -95,6 +95,7 @@ static const struct { unsigned flag:8; char opt_char; } opt_array[] = {
        { _DPRINTK_FLAGS_INCL_SOURCENAME, 's' },
        { _DPRINTK_FLAGS_INCL_LINENO, 'l' },
        { _DPRINTK_FLAGS_INCL_TID, 't' },
+       { _DPRINTK_FLAGS_INCL_STACK, 'd' },
        { _DPRINTK_FLAGS_NONE, '_' },
 };