aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorJason Baron <jbaron@redhat.com>2009-02-05 11:51:38 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2009-03-24 19:38:26 -0400
commite9d376f0fa66bd630fe27403669c6ae6c22a868f (patch)
tree6eadef32eb421647ae98d88341b9aceb259aaf22 /include
parent095160aee954688a9bad225952c4bee546541e19 (diff)
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>
Diffstat (limited to 'include')
-rw-r--r--include/asm-generic/vmlinux.lds.h15
-rw-r--r--include/linux/device.h2
-rw-r--r--include/linux/dynamic_debug.h88
-rw-r--r--include/linux/dynamic_printk.h93
-rw-r--r--include/linux/kernel.h4
5 files changed, 97 insertions, 105 deletions
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index c61fab1dd2f8..aca40b93bd28 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -80,6 +80,11 @@
80 VMLINUX_SYMBOL(__start___tracepoints) = .; \ 80 VMLINUX_SYMBOL(__start___tracepoints) = .; \
81 *(__tracepoints) \ 81 *(__tracepoints) \
82 VMLINUX_SYMBOL(__stop___tracepoints) = .; \ 82 VMLINUX_SYMBOL(__stop___tracepoints) = .; \
83 /* implement dynamic printk debug */ \
84 . = ALIGN(8); \
85 VMLINUX_SYMBOL(__start___verbose) = .; \
86 *(__verbose) \
87 VMLINUX_SYMBOL(__stop___verbose) = .; \
83 LIKELY_PROFILE() \ 88 LIKELY_PROFILE() \
84 BRANCH_PROFILE() 89 BRANCH_PROFILE()
85 90
@@ -309,15 +314,7 @@
309 CPU_DISCARD(init.data) \ 314 CPU_DISCARD(init.data) \
310 CPU_DISCARD(init.rodata) \ 315 CPU_DISCARD(init.rodata) \
311 MEM_DISCARD(init.data) \ 316 MEM_DISCARD(init.data) \
312 MEM_DISCARD(init.rodata) \ 317 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) = .;
321 318
322#define INIT_TEXT \ 319#define INIT_TEXT \
323 *(.init.text) \ 320 *(.init.text) \
diff --git a/include/linux/device.h b/include/linux/device.h
index f98d0cfb4f81..2918c0e8fdfd 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -582,7 +582,7 @@ extern const char *dev_driver_string(const struct device *dev);
582#if defined(DEBUG) 582#if defined(DEBUG)
583#define dev_dbg(dev, format, arg...) \ 583#define dev_dbg(dev, format, arg...) \
584 dev_printk(KERN_DEBUG , dev , format , ## arg) 584 dev_printk(KERN_DEBUG , dev , format , ## arg)
585#elif defined(CONFIG_DYNAMIC_PRINTK_DEBUG) 585#elif defined(CONFIG_DYNAMIC_DEBUG)
586#define dev_dbg(dev, format, ...) do { \ 586#define dev_dbg(dev, format, ...) do { \
587 dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \ 587 dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
588 } while (0) 588 } while (0)
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h
new file mode 100644
index 000000000000..07781aaa1164
--- /dev/null
+++ b/include/linux/dynamic_debug.h
@@ -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 */
8extern long long dynamic_debug_enabled;
9extern 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 */
16struct _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
39int ddebug_add_module(struct _ddebug *tab, unsigned int n,
40 const char *modname);
41
42#if defined(CONFIG_DYNAMIC_DEBUG)
43extern 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
79static 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
diff --git a/include/linux/dynamic_printk.h b/include/linux/dynamic_printk.h
deleted file mode 100644
index 2d528d009074..000000000000
--- a/include/linux/dynamic_printk.h
+++ /dev/null
@@ -1,93 +0,0 @@
1#ifndef _DYNAMIC_PRINTK_H
2#define _DYNAMIC_PRINTK_H
3
4#define DYNAMIC_DEBUG_HASH_BITS 6
5#define DEBUG_HASH_TABLE_SIZE (1 << DYNAMIC_DEBUG_HASH_BITS)
6
7#define TYPE_BOOLEAN 1
8
9#define DYNAMIC_ENABLED_ALL 0
10#define DYNAMIC_ENABLED_NONE 1
11#define DYNAMIC_ENABLED_SOME 2
12
13extern int dynamic_enabled;
14
15/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
16 * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
17 * use independent hash functions, to reduce the chance of false positives.
18 */
19extern long long dynamic_printk_enabled;
20extern long long dynamic_printk_enabled2;
21
22struct mod_debug {
23 char *modname;
24 char *logical_modname;
25 char *flag_names;
26 int type;
27 int hash;
28 int hash2;
29} __attribute__((aligned(8)));
30
31int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
32 char *flags, int hash, int hash2);
33
34#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
35extern int unregister_dynamic_debug_module(char *mod_name);
36extern int __dynamic_dbg_enabled_helper(char *modname, int type,
37 int value, int hash);
38
39#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ \
40 int __ret = 0; \
41 if (unlikely((dynamic_printk_enabled & (1LL << DEBUG_HASH)) && \
42 (dynamic_printk_enabled2 & (1LL << DEBUG_HASH2)))) \
43 __ret = __dynamic_dbg_enabled_helper(module, type, \
44 value, hash);\
45 __ret; })
46
47#define dynamic_pr_debug(fmt, ...) do { \
48 static char mod_name[] \
49 __attribute__((section("__verbose_strings"))) \
50 = KBUILD_MODNAME; \
51 static struct mod_debug descriptor \
52 __used \
53 __attribute__((section("__verbose"), aligned(8))) = \
54 { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
55 if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
56 0, 0, DEBUG_HASH)) \
57 printk(KERN_DEBUG KBUILD_MODNAME ":" fmt, \
58 ##__VA_ARGS__); \
59 } while (0)
60
61#define dynamic_dev_dbg(dev, format, ...) do { \
62 static char mod_name[] \
63 __attribute__((section("__verbose_strings"))) \
64 = KBUILD_MODNAME; \
65 static struct mod_debug descriptor \
66 __used \
67 __attribute__((section("__verbose"), aligned(8))) = \
68 { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
69 if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
70 0, 0, DEBUG_HASH)) \
71 dev_printk(KERN_DEBUG, dev, \
72 KBUILD_MODNAME ": " format, \
73 ##__VA_ARGS__); \
74 } while (0)
75
76#else
77
78static inline int unregister_dynamic_debug_module(const char *mod_name)
79{
80 return 0;
81}
82static inline int __dynamic_dbg_enabled_helper(char *modname, int type,
83 int value, int hash)
84{
85 return 0;
86}
87
88#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ 0; })
89#define dynamic_pr_debug(fmt, ...) do { } while (0)
90#define dynamic_dev_dbg(dev, format, ...) do { } while (0)
91#endif
92
93#endif
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 7fa371898e3e..b5496ecbec71 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -16,7 +16,7 @@
16#include <linux/log2.h> 16#include <linux/log2.h>
17#include <linux/typecheck.h> 17#include <linux/typecheck.h>
18#include <linux/ratelimit.h> 18#include <linux/ratelimit.h>
19#include <linux/dynamic_printk.h> 19#include <linux/dynamic_debug.h>
20#include <asm/byteorder.h> 20#include <asm/byteorder.h>
21#include <asm/bug.h> 21#include <asm/bug.h>
22 22
@@ -358,7 +358,7 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
358#if defined(DEBUG) 358#if defined(DEBUG)
359#define pr_debug(fmt, ...) \ 359#define pr_debug(fmt, ...) \
360 printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__) 360 printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
361#elif defined(CONFIG_DYNAMIC_PRINTK_DEBUG) 361#elif defined(CONFIG_DYNAMIC_DEBUG)
362#define pr_debug(fmt, ...) do { \ 362#define pr_debug(fmt, ...) do { \
363 dynamic_pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \ 363 dynamic_pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \
364 } while (0) 364 } while (0)