Skip to content

Commit e9d376f

Browse files
jibarongregkh
authored andcommitted
dynamic debug: combine dprintk and dynamic printk
This patch combines Greg Bank's dprintk() work with the existing dynamic printk patchset, we are now calling it 'dynamic debug'. The new feature of this patchset is a richer /debugfs control file interface, (an example output from my system is at the bottom), which allows fined grained control over the the debug output. The output can be controlled by function, file, module, format string, and line number. for example, enabled all debug messages in module 'nf_conntrack': echo -n 'module nf_conntrack +p' > /mnt/debugfs/dynamic_debug/control to disable them: echo -n 'module nf_conntrack -p' > /mnt/debugfs/dynamic_debug/control A further explanation can be found in the documentation patch. Signed-off-by: Greg Banks <gnb@sgi.com> Signed-off-by: Jason Baron <jbaron@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
1 parent 095160a commit e9d376f

File tree

13 files changed

+867
-543
lines changed

13 files changed

+867
-543
lines changed

Documentation/kernel-parameters.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,11 +1816,6 @@ and is between 256 and 4096 characters. It is defined in the file
18161816
autoconfiguration.
18171817
Ranges are in pairs (memory base and size).
18181818

1819-
dynamic_printk Enables pr_debug()/dev_dbg() calls if
1820-
CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled.
1821-
These can also be switched on/off via
1822-
<debugfs>/dynamic_printk/modules
1823-
18241819
print-fatal-signals=
18251820
[KNL] debug: print fatal signals
18261821
print-fatal-signals=1: print segfault info to

include/asm-generic/vmlinux.lds.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@
8080
VMLINUX_SYMBOL(__start___tracepoints) = .; \
8181
*(__tracepoints) \
8282
VMLINUX_SYMBOL(__stop___tracepoints) = .; \
83+
/* implement dynamic printk debug */ \
84+
. = ALIGN(8); \
85+
VMLINUX_SYMBOL(__start___verbose) = .; \
86+
*(__verbose) \
87+
VMLINUX_SYMBOL(__stop___verbose) = .; \
8388
LIKELY_PROFILE() \
8489
BRANCH_PROFILE()
8590

@@ -309,15 +314,7 @@
309314
CPU_DISCARD(init.data) \
310315
CPU_DISCARD(init.rodata) \
311316
MEM_DISCARD(init.data) \
312-
MEM_DISCARD(init.rodata) \
313-
/* implement dynamic printk debug */ \
314-
VMLINUX_SYMBOL(__start___verbose_strings) = .; \
315-
*(__verbose_strings) \
316-
VMLINUX_SYMBOL(__stop___verbose_strings) = .; \
317-
. = ALIGN(8); \
318-
VMLINUX_SYMBOL(__start___verbose) = .; \
319-
*(__verbose) \
320-
VMLINUX_SYMBOL(__stop___verbose) = .;
317+
MEM_DISCARD(init.rodata)
321318

322319
#define INIT_TEXT \
323320
*(.init.text) \

include/linux/device.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,7 +582,7 @@ extern const char *dev_driver_string(const struct device *dev);
582582
#if defined(DEBUG)
583583
#define dev_dbg(dev, format, arg...) \
584584
dev_printk(KERN_DEBUG , dev , format , ## arg)
585-
#elif defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
585+
#elif defined(CONFIG_DYNAMIC_DEBUG)
586586
#define dev_dbg(dev, format, ...) do { \
587587
dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
588588
} while (0)

include/linux/dynamic_debug.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#ifndef _DYNAMIC_DEBUG_H
2+
#define _DYNAMIC_DEBUG_H
3+
4+
/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
5+
* bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
6+
* use independent hash functions, to reduce the chance of false positives.
7+
*/
8+
extern long long dynamic_debug_enabled;
9+
extern long long dynamic_debug_enabled2;
10+
11+
/*
12+
* An instance of this structure is created in a special
13+
* ELF section at every dynamic debug callsite. At runtime,
14+
* the special section is treated as an array of these.
15+
*/
16+
struct _ddebug {
17+
/*
18+
* These fields are used to drive the user interface
19+
* for selecting and displaying debug callsites.
20+
*/
21+
const char *modname;
22+
const char *function;
23+
const char *filename;
24+
const char *format;
25+
char primary_hash;
26+
char secondary_hash;
27+
unsigned int lineno:24;
28+
/*
29+
* The flags field controls the behaviour at the callsite.
30+
* The bits here are changed dynamically when the user
31+
* writes commands to <debugfs>/dynamic_debug/ddebug
32+
*/
33+
#define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */
34+
#define _DPRINTK_FLAGS_DEFAULT 0
35+
unsigned int flags:8;
36+
} __attribute__((aligned(8)));
37+
38+
39+
int ddebug_add_module(struct _ddebug *tab, unsigned int n,
40+
const char *modname);
41+
42+
#if defined(CONFIG_DYNAMIC_DEBUG)
43+
extern int ddebug_remove_module(char *mod_name);
44+
45+
#define __dynamic_dbg_enabled(dd) ({ \
46+
int __ret = 0; \
47+
if (unlikely((dynamic_debug_enabled & (1LL << DEBUG_HASH)) && \
48+
(dynamic_debug_enabled2 & (1LL << DEBUG_HASH2)))) \
49+
if (unlikely(dd.flags)) \
50+
__ret = 1; \
51+
__ret; })
52+
53+
#define dynamic_pr_debug(fmt, ...) do { \
54+
static struct _ddebug descriptor \
55+
__used \
56+
__attribute__((section("__verbose"), aligned(8))) = \
57+
{ KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH, \
58+
DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \
59+
if (__dynamic_dbg_enabled(descriptor)) \
60+
printk(KERN_DEBUG KBUILD_MODNAME ":" fmt, \
61+
##__VA_ARGS__); \
62+
} while (0)
63+
64+
65+
#define dynamic_dev_dbg(dev, fmt, ...) do { \
66+
static struct _ddebug descriptor \
67+
__used \
68+
__attribute__((section("__verbose"), aligned(8))) = \
69+
{ KBUILD_MODNAME, __func__, __FILE__, fmt, DEBUG_HASH, \
70+
DEBUG_HASH2, __LINE__, _DPRINTK_FLAGS_DEFAULT }; \
71+
if (__dynamic_dbg_enabled(descriptor)) \
72+
dev_printk(KERN_DEBUG, dev, \
73+
KBUILD_MODNAME ": " fmt, \
74+
##__VA_ARGS__); \
75+
} while (0)
76+
77+
#else
78+
79+
static inline int ddebug_remove_module(char *mod)
80+
{
81+
return 0;
82+
}
83+
84+
#define dynamic_pr_debug(fmt, ...) do { } while (0)
85+
#define dynamic_dev_dbg(dev, format, ...) do { } while (0)
86+
#endif
87+
88+
#endif

include/linux/dynamic_printk.h

Lines changed: 0 additions & 93 deletions
This file was deleted.

include/linux/kernel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include <linux/log2.h>
1717
#include <linux/typecheck.h>
1818
#include <linux/ratelimit.h>
19-
#include <linux/dynamic_printk.h>
19+
#include <linux/dynamic_debug.h>
2020
#include <asm/byteorder.h>
2121
#include <asm/bug.h>
2222

@@ -358,7 +358,7 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
358358
#if defined(DEBUG)
359359
#define pr_debug(fmt, ...) \
360360
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
361-
#elif defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
361+
#elif defined(CONFIG_DYNAMIC_DEBUG)
362362
#define pr_debug(fmt, ...) do { \
363363
dynamic_pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \
364364
} while (0)

kernel/module.c

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
822822
mutex_lock(&module_mutex);
823823
/* Store the name of the last unloaded module for diagnostic purposes */
824824
strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
825-
unregister_dynamic_debug_module(mod->name);
825+
ddebug_remove_module(mod->name);
826826
free_module(mod);
827827

828828
out:
@@ -1827,19 +1827,13 @@ static inline void add_kallsyms(struct module *mod,
18271827
}
18281828
#endif /* CONFIG_KALLSYMS */
18291829

1830-
static void dynamic_printk_setup(struct mod_debug *debug, unsigned int num)
1830+
static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num)
18311831
{
1832-
#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
1833-
unsigned int i;
1834-
1835-
for (i = 0; i < num; i++) {
1836-
register_dynamic_debug_module(debug[i].modname,
1837-
debug[i].type,
1838-
debug[i].logical_modname,
1839-
debug[i].flag_names,
1840-
debug[i].hash, debug[i].hash2);
1841-
}
1842-
#endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */
1832+
#ifdef CONFIG_DYNAMIC_DEBUG
1833+
if (ddebug_add_module(debug, num, debug->modname))
1834+
printk(KERN_ERR "dynamic debug error adding module: %s\n",
1835+
debug->modname);
1836+
#endif
18431837
}
18441838

18451839
static void *module_alloc_update_bounds(unsigned long size)
@@ -2213,12 +2207,13 @@ static noinline struct module *load_module(void __user *umod,
22132207
add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
22142208

22152209
if (!mod->taints) {
2216-
struct mod_debug *debug;
2210+
struct _ddebug *debug;
22172211
unsigned int num_debug;
22182212

22192213
debug = section_objs(hdr, sechdrs, secstrings, "__verbose",
22202214
sizeof(*debug), &num_debug);
2221-
dynamic_printk_setup(debug, num_debug);
2215+
if (debug)
2216+
dynamic_debug_setup(debug, num_debug);
22222217
}
22232218

22242219
/* sechdrs[0].sh_size is always zero */

lib/Kconfig.debug

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ config BUILD_DOCSRC
847847

848848
Say N if you are unsure.
849849

850-
config DYNAMIC_PRINTK_DEBUG
850+
config DYNAMIC_DEBUG
851851
bool "Enable dynamic printk() call support"
852852
default n
853853
depends on PRINTK

lib/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ obj-$(CONFIG_HAVE_LMB) += lmb.o
8282

8383
obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
8484

85-
obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
85+
obj-$(CONFIG_DYNAMIC_DEBUG) += dynamic_debug.o
8686

8787
hostprogs-y := gen_crc32table
8888
clean-files := crc32table.h

0 commit comments

Comments
 (0)