aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--Documentation/kernel-parameters.txt5
-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
-rw-r--r--kernel/module.c25
-rw-r--r--lib/Kconfig.debug2
-rw-r--r--lib/Makefile2
-rw-r--r--lib/dynamic_debug.c756
-rw-r--r--lib/dynamic_printk.c414
-rw-r--r--net/netfilter/nf_conntrack_pptp.c2
-rw-r--r--scripts/Makefile.lib2
13 files changed, 867 insertions, 543 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 54f21a5c262b..3a1aa8a4affc 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1816,11 +1816,6 @@ and is between 256 and 4096 characters. It is defined in the file
1816 autoconfiguration. 1816 autoconfiguration.
1817 Ranges are in pairs (memory base and size). 1817 Ranges are in pairs (memory base and size).
1818 1818
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
1824 print-fatal-signals= 1819 print-fatal-signals=
1825 [KNL] debug: print fatal signals 1820 [KNL] debug: print fatal signals
1826 print-fatal-signals=1: print segfault info to 1821 print-fatal-signals=1: print segfault info to
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)
diff --git a/kernel/module.c b/kernel/module.c
index 1196f5d11700..77672233387f 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -822,7 +822,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
822 mutex_lock(&module_mutex); 822 mutex_lock(&module_mutex);
823 /* Store the name of the last unloaded module for diagnostic purposes */ 823 /* Store the name of the last unloaded module for diagnostic purposes */
824 strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); 824 strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
825 unregister_dynamic_debug_module(mod->name); 825 ddebug_remove_module(mod->name);
826 free_module(mod); 826 free_module(mod);
827 827
828 out: 828 out:
@@ -1827,19 +1827,13 @@ static inline void add_kallsyms(struct module *mod,
1827} 1827}
1828#endif /* CONFIG_KALLSYMS */ 1828#endif /* CONFIG_KALLSYMS */
1829 1829
1830static void dynamic_printk_setup(struct mod_debug *debug, unsigned int num) 1830static void dynamic_debug_setup(struct _ddebug *debug, unsigned int num)
1831{ 1831{
1832#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG 1832#ifdef CONFIG_DYNAMIC_DEBUG
1833 unsigned int i; 1833 if (ddebug_add_module(debug, num, debug->modname))
1834 1834 printk(KERN_ERR "dynamic debug error adding module: %s\n",
1835 for (i = 0; i < num; i++) { 1835 debug->modname);
1836 register_dynamic_debug_module(debug[i].modname, 1836#endif
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 */
1843} 1837}
1844 1838
1845static void *module_alloc_update_bounds(unsigned long size) 1839static void *module_alloc_update_bounds(unsigned long size)
@@ -2213,12 +2207,13 @@ static noinline struct module *load_module(void __user *umod,
2213 add_kallsyms(mod, sechdrs, symindex, strindex, secstrings); 2207 add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
2214 2208
2215 if (!mod->taints) { 2209 if (!mod->taints) {
2216 struct mod_debug *debug; 2210 struct _ddebug *debug;
2217 unsigned int num_debug; 2211 unsigned int num_debug;
2218 2212
2219 debug = section_objs(hdr, sechdrs, secstrings, "__verbose", 2213 debug = section_objs(hdr, sechdrs, secstrings, "__verbose",
2220 sizeof(*debug), &num_debug); 2214 sizeof(*debug), &num_debug);
2221 dynamic_printk_setup(debug, num_debug); 2215 if (debug)
2216 dynamic_debug_setup(debug, num_debug);
2222 } 2217 }
2223 2218
2224 /* sechdrs[0].sh_size is always zero */ 2219 /* sechdrs[0].sh_size is always zero */
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 1bcf9cd4baa0..0dd1c04c7323 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -847,7 +847,7 @@ config BUILD_DOCSRC
847 847
848 Say N if you are unsure. 848 Say N if you are unsure.
849 849
850config DYNAMIC_PRINTK_DEBUG 850config DYNAMIC_DEBUG
851 bool "Enable dynamic printk() call support" 851 bool "Enable dynamic printk() call support"
852 default n 852 default n
853 depends on PRINTK 853 depends on PRINTK
diff --git a/lib/Makefile b/lib/Makefile
index 32b0e64ded27..8633d6be9d21 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -82,7 +82,7 @@ obj-$(CONFIG_HAVE_LMB) += lmb.o
82 82
83obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o 83obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
84 84
85obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o 85obj-$(CONFIG_DYNAMIC_DEBUG) += dynamic_debug.o
86 86
87hostprogs-y := gen_crc32table 87hostprogs-y := gen_crc32table
88clean-files := crc32table.h 88clean-files := crc32table.h
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
new file mode 100644
index 000000000000..9e123ae326bc
--- /dev/null
+++ b/lib/dynamic_debug.c
@@ -0,0 +1,756 @@
1/*
2 * lib/dynamic_debug.c
3 *
4 * make pr_debug()/dev_dbg() calls runtime configurable based upon their
5 * source module.
6 *
7 * Copyright (C) 2008 Jason Baron <jbaron@redhat.com>
8 * By Greg Banks <gnb@melbourne.sgi.com>
9 * Copyright (c) 2008 Silicon Graphics Inc. All Rights Reserved.
10 */
11
12#include <linux/kernel.h>
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/kallsyms.h>
16#include <linux/version.h>
17#include <linux/types.h>
18#include <linux/mutex.h>
19#include <linux/proc_fs.h>
20#include <linux/seq_file.h>
21#include <linux/list.h>
22#include <linux/sysctl.h>
23#include <linux/ctype.h>
24#include <linux/uaccess.h>
25#include <linux/dynamic_debug.h>
26#include <linux/debugfs.h>
27
28extern struct _ddebug __start___verbose[];
29extern struct _ddebug __stop___verbose[];
30
31/* dynamic_debug_enabled, and dynamic_debug_enabled2 are bitmasks in which
32 * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
33 * use independent hash functions, to reduce the chance of false positives.
34 */
35long long dynamic_debug_enabled;
36EXPORT_SYMBOL_GPL(dynamic_debug_enabled);
37long long dynamic_debug_enabled2;
38EXPORT_SYMBOL_GPL(dynamic_debug_enabled2);
39
40struct ddebug_table {
41 struct list_head link;
42 char *mod_name;
43 unsigned int num_ddebugs;
44 unsigned int num_enabled;
45 struct _ddebug *ddebugs;
46};
47
48struct ddebug_query {
49 const char *filename;
50 const char *module;
51 const char *function;
52 const char *format;
53 unsigned int first_lineno, last_lineno;
54};
55
56struct ddebug_iter {
57 struct ddebug_table *table;
58 unsigned int idx;
59};
60
61static DEFINE_MUTEX(ddebug_lock);
62static LIST_HEAD(ddebug_tables);
63static int verbose = 0;
64
65/* Return the last part of a pathname */
66static inline const char *basename(const char *path)
67{
68 const char *tail = strrchr(path, '/');
69 return tail ? tail+1 : path;
70}
71
72/* format a string into buf[] which describes the _ddebug's flags */
73static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,
74 size_t maxlen)
75{
76 char *p = buf;
77
78 BUG_ON(maxlen < 4);
79 if (dp->flags & _DPRINTK_FLAGS_PRINT)
80 *p++ = 'p';
81 if (p == buf)
82 *p++ = '-';
83 *p = '\0';
84
85 return buf;
86}
87
88/*
89 * must be called with ddebug_lock held
90 */
91
92static int disabled_hash(char hash, bool first_table)
93{
94 struct ddebug_table *dt;
95 char table_hash_value;
96
97 list_for_each_entry(dt, &ddebug_tables, link) {
98 if (first_table)
99 table_hash_value = dt->ddebugs->primary_hash;
100 else
101 table_hash_value = dt->ddebugs->secondary_hash;
102 if (dt->num_enabled && (hash == table_hash_value))
103 return 0;
104 }
105 return 1;
106}
107
108/*
109 * Search the tables for _ddebug's which match the given
110 * `query' and apply the `flags' and `mask' to them. Tells
111 * the user which ddebug's were changed, or whether none
112 * were matched.
113 */
114static void ddebug_change(const struct ddebug_query *query,
115 unsigned int flags, unsigned int mask)
116{
117 int i;
118 struct ddebug_table *dt;
119 unsigned int newflags;
120 unsigned int nfound = 0;
121 char flagbuf[8];
122
123 /* search for matching ddebugs */
124 mutex_lock(&ddebug_lock);
125 list_for_each_entry(dt, &ddebug_tables, link) {
126
127 /* match against the module name */
128 if (query->module != NULL &&
129 strcmp(query->module, dt->mod_name))
130 continue;
131
132 for (i = 0 ; i < dt->num_ddebugs ; i++) {
133 struct _ddebug *dp = &dt->ddebugs[i];
134
135 /* match against the source filename */
136 if (query->filename != NULL &&
137 strcmp(query->filename, dp->filename) &&
138 strcmp(query->filename, basename(dp->filename)))
139 continue;
140
141 /* match against the function */
142 if (query->function != NULL &&
143 strcmp(query->function, dp->function))
144 continue;
145
146 /* match against the format */
147 if (query->format != NULL &&
148 strstr(dp->format, query->format) == NULL)
149 continue;
150
151 /* match against the line number range */
152 if (query->first_lineno &&
153 dp->lineno < query->first_lineno)
154 continue;
155 if (query->last_lineno &&
156 dp->lineno > query->last_lineno)
157 continue;
158
159 nfound++;
160
161 newflags = (dp->flags & mask) | flags;
162 if (newflags == dp->flags)
163 continue;
164
165 if (!newflags)
166 dt->num_enabled--;
167 else if (!dp-flags)
168 dt->num_enabled++;
169 dp->flags = newflags;
170 if (newflags) {
171 dynamic_debug_enabled |=
172 (1LL << dp->primary_hash);
173 dynamic_debug_enabled2 |=
174 (1LL << dp->secondary_hash);
175 } else {
176 if (disabled_hash(dp->primary_hash, true))
177 dynamic_debug_enabled &=
178 ~(1LL << dp->primary_hash);
179 if (disabled_hash(dp->secondary_hash, false))
180 dynamic_debug_enabled2 &=
181 ~(1LL << dp->secondary_hash);
182 }
183 if (verbose)
184 printk(KERN_INFO
185 "ddebug: changed %s:%d [%s]%s %s\n",
186 dp->filename, dp->lineno,
187 dt->mod_name, dp->function,
188 ddebug_describe_flags(dp, flagbuf,
189 sizeof(flagbuf)));
190 }
191 }
192 mutex_unlock(&ddebug_lock);
193
194 if (!nfound && verbose)
195 printk(KERN_INFO "ddebug: no matches for query\n");
196}
197
198/*
199 * Wrapper around strsep() to collapse the multiple empty tokens
200 * that it returns when fed sequences of separator characters.
201 * Now, if we had strtok_r()...
202 */
203static inline char *nearly_strtok_r(char **p, const char *sep)
204{
205 char *r;
206
207 while ((r = strsep(p, sep)) != NULL && *r == '\0')
208 ;
209 return r;
210}
211
212/*
213 * Split the buffer `buf' into space-separated words.
214 * Return the number of such words or <0 on error.
215 */
216static int ddebug_tokenize(char *buf, char *words[], int maxwords)
217{
218 int nwords = 0;
219
220 while (nwords < maxwords &&
221 (words[nwords] = nearly_strtok_r(&buf, " \t\r\n")) != NULL)
222 nwords++;
223 if (buf)
224 return -EINVAL; /* ran out of words[] before bytes */
225
226 if (verbose) {
227 int i;
228 printk(KERN_INFO "%s: split into words:", __func__);
229 for (i = 0 ; i < nwords ; i++)
230 printk(" \"%s\"", words[i]);
231 printk("\n");
232 }
233
234 return nwords;
235}
236
237/*
238 * Parse a single line number. Note that the empty string ""
239 * is treated as a special case and converted to zero, which
240 * is later treated as a "don't care" value.
241 */
242static inline int parse_lineno(const char *str, unsigned int *val)
243{
244 char *end = NULL;
245 BUG_ON(str == NULL);
246 if (*str == '\0') {
247 *val = 0;
248 return 0;
249 }
250 *val = simple_strtoul(str, &end, 10);
251 return end == NULL || end == str || *end != '\0' ? -EINVAL : 0;
252}
253
254/*
255 * Undo octal escaping in a string, inplace. This is useful to
256 * allow the user to express a query which matches a format
257 * containing embedded spaces.
258 */
259#define isodigit(c) ((c) >= '0' && (c) <= '7')
260static char *unescape(char *str)
261{
262 char *in = str;
263 char *out = str;
264
265 while (*in) {
266 if (*in == '\\') {
267 if (in[1] == '\\') {
268 *out++ = '\\';
269 in += 2;
270 continue;
271 } else if (in[1] == 't') {
272 *out++ = '\t';
273 in += 2;
274 continue;
275 } else if (in[1] == 'n') {
276 *out++ = '\n';
277 in += 2;
278 continue;
279 } else if (isodigit(in[1]) &&
280 isodigit(in[2]) &&
281 isodigit(in[3])) {
282 *out++ = ((in[1] - '0')<<6) |
283 ((in[2] - '0')<<3) |
284 (in[3] - '0');
285 in += 4;
286 continue;
287 }
288 }
289 *out++ = *in++;
290 }
291 *out = '\0';
292
293 return str;
294}
295
296/*
297 * Parse words[] as a ddebug query specification, which is a series
298 * of (keyword, value) pairs chosen from these possibilities:
299 *
300 * func <function-name>
301 * file <full-pathname>
302 * file <base-filename>
303 * module <module-name>
304 * format <escaped-string-to-find-in-format>
305 * line <lineno>
306 * line <first-lineno>-<last-lineno> // where either may be empty
307 */
308static int ddebug_parse_query(char *words[], int nwords,
309 struct ddebug_query *query)
310{
311 unsigned int i;
312
313 /* check we have an even number of words */
314 if (nwords % 2 != 0)
315 return -EINVAL;
316 memset(query, 0, sizeof(*query));
317
318 for (i = 0 ; i < nwords ; i += 2) {
319 if (!strcmp(words[i], "func"))
320 query->function = words[i+1];
321 else if (!strcmp(words[i], "file"))
322 query->filename = words[i+1];
323 else if (!strcmp(words[i], "module"))
324 query->module = words[i+1];
325 else if (!strcmp(words[i], "format"))
326 query->format = unescape(words[i+1]);
327 else if (!strcmp(words[i], "line")) {
328 char *first = words[i+1];
329 char *last = strchr(first, '-');
330 if (last)
331 *last++ = '\0';
332 if (parse_lineno(first, &query->first_lineno) < 0)
333 return -EINVAL;
334 if (last != NULL) {
335 /* range <first>-<last> */
336 if (parse_lineno(last, &query->last_lineno) < 0)
337 return -EINVAL;
338 } else {
339 query->last_lineno = query->first_lineno;
340 }
341 } else {
342 if (verbose)
343 printk(KERN_ERR "%s: unknown keyword \"%s\"\n",
344 __func__, words[i]);
345 return -EINVAL;
346 }
347 }
348
349 if (verbose)
350 printk(KERN_INFO "%s: q->function=\"%s\" q->filename=\"%s\" "
351 "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n",
352 __func__, query->function, query->filename,
353 query->module, query->format, query->first_lineno,
354 query->last_lineno);
355
356 return 0;
357}
358
359/*
360 * Parse `str' as a flags specification, format [-+=][p]+.
361 * Sets up *maskp and *flagsp to be used when changing the
362 * flags fields of matched _ddebug's. Returns 0 on success
363 * or <0 on error.
364 */
365static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
366 unsigned int *maskp)
367{
368 unsigned flags = 0;
369 int op = '=';
370
371 switch (*str) {
372 case '+':
373 case '-':
374 case '=':
375 op = *str++;
376 break;
377 default:
378 return -EINVAL;
379 }
380 if (verbose)
381 printk(KERN_INFO "%s: op='%c'\n", __func__, op);
382
383 for ( ; *str ; ++str) {
384 switch (*str) {
385 case 'p':
386 flags |= _DPRINTK_FLAGS_PRINT;
387 break;
388 default:
389 return -EINVAL;
390 }
391 }
392 if (flags == 0)
393 return -EINVAL;
394 if (verbose)
395 printk(KERN_INFO "%s: flags=0x%x\n", __func__, flags);
396
397 /* calculate final *flagsp, *maskp according to mask and op */
398 switch (op) {
399 case '=':
400 *maskp = 0;
401 *flagsp = flags;
402 break;
403 case '+':
404 *maskp = ~0U;
405 *flagsp = flags;
406 break;
407 case '-':
408 *maskp = ~flags;
409 *flagsp = 0;
410 break;
411 }
412 if (verbose)
413 printk(KERN_INFO "%s: *flagsp=0x%x *maskp=0x%x\n",
414 __func__, *flagsp, *maskp);
415 return 0;
416}
417
418/*
419 * File_ops->write method for <debugfs>/dynamic_debug/conrol. Gathers the
420 * command text from userspace, parses and executes it.
421 */
422static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf,
423 size_t len, loff_t *offp)
424{
425 unsigned int flags = 0, mask = 0;
426 struct ddebug_query query;
427#define MAXWORDS 9
428 int nwords;
429 char *words[MAXWORDS];
430 char tmpbuf[256];
431
432 if (len == 0)
433 return 0;
434 /* we don't check *offp -- multiple writes() are allowed */
435 if (len > sizeof(tmpbuf)-1)
436 return -E2BIG;
437 if (copy_from_user(tmpbuf, ubuf, len))
438 return -EFAULT;
439 tmpbuf[len] = '\0';
440 if (verbose)
441 printk(KERN_INFO "%s: read %d bytes from userspace\n",
442 __func__, (int)len);
443
444 nwords = ddebug_tokenize(tmpbuf, words, MAXWORDS);
445 if (nwords < 0)
446 return -EINVAL;
447 if (ddebug_parse_query(words, nwords-1, &query))
448 return -EINVAL;
449 if (ddebug_parse_flags(words[nwords-1], &flags, &mask))
450 return -EINVAL;
451
452 /* actually go and implement the change */
453 ddebug_change(&query, flags, mask);
454
455 *offp += len;
456 return len;
457}
458
459/*
460 * Set the iterator to point to the first _ddebug object
461 * and return a pointer to that first object. Returns
462 * NULL if there are no _ddebugs at all.
463 */
464static struct _ddebug *ddebug_iter_first(struct ddebug_iter *iter)
465{
466 if (list_empty(&ddebug_tables)) {
467 iter->table = NULL;
468 iter->idx = 0;
469 return NULL;
470 }
471 iter->table = list_entry(ddebug_tables.next,
472 struct ddebug_table, link);
473 iter->idx = 0;
474 return &iter->table->ddebugs[iter->idx];
475}
476
477/*
478 * Advance the iterator to point to the next _ddebug
479 * object from the one the iterator currently points at,
480 * and returns a pointer to the new _ddebug. Returns
481 * NULL if the iterator has seen all the _ddebugs.
482 */
483static struct _ddebug *ddebug_iter_next(struct ddebug_iter *iter)
484{
485 if (iter->table == NULL)
486 return NULL;
487 if (++iter->idx == iter->table->num_ddebugs) {
488 /* iterate to next table */
489 iter->idx = 0;
490 if (list_is_last(&iter->table->link, &ddebug_tables)) {
491 iter->table = NULL;
492 return NULL;
493 }
494 iter->table = list_entry(iter->table->link.next,
495 struct ddebug_table, link);
496 }
497 return &iter->table->ddebugs[iter->idx];
498}
499
500/*
501 * Seq_ops start method. Called at the start of every
502 * read() call from userspace. Takes the ddebug_lock and
503 * seeks the seq_file's iterator to the given position.
504 */
505static void *ddebug_proc_start(struct seq_file *m, loff_t *pos)
506{
507 struct ddebug_iter *iter = m->private;
508 struct _ddebug *dp;
509 int n = *pos;
510
511 if (verbose)
512 printk(KERN_INFO "%s: called m=%p *pos=%lld\n",
513 __func__, m, (unsigned long long)*pos);
514
515 mutex_lock(&ddebug_lock);
516
517 if (!n)
518 return SEQ_START_TOKEN;
519 if (n < 0)
520 return NULL;
521 dp = ddebug_iter_first(iter);
522 while (dp != NULL && --n > 0)
523 dp = ddebug_iter_next(iter);
524 return dp;
525}
526
527/*
528 * Seq_ops next method. Called several times within a read()
529 * call from userspace, with ddebug_lock held. Walks to the
530 * next _ddebug object with a special case for the header line.
531 */
532static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos)
533{
534 struct ddebug_iter *iter = m->private;
535 struct _ddebug *dp;
536
537 if (verbose)
538 printk(KERN_INFO "%s: called m=%p p=%p *pos=%lld\n",
539 __func__, m, p, (unsigned long long)*pos);
540
541 if (p == SEQ_START_TOKEN)
542 dp = ddebug_iter_first(iter);
543 else
544 dp = ddebug_iter_next(iter);
545 ++*pos;
546 return dp;
547}
548
549/*
550 * Seq_ops show method. Called several times within a read()
551 * call from userspace, with ddebug_lock held. Formats the
552 * current _ddebug as a single human-readable line, with a
553 * special case for the header line.
554 */
555static int ddebug_proc_show(struct seq_file *m, void *p)
556{
557 struct ddebug_iter *iter = m->private;
558 struct _ddebug *dp = p;
559 char flagsbuf[8];
560
561 if (verbose)
562 printk(KERN_INFO "%s: called m=%p p=%p\n",
563 __func__, m, p);
564
565 if (p == SEQ_START_TOKEN) {
566 seq_puts(m,
567 "# filename:lineno [module]function flags format\n");
568 return 0;
569 }
570
571 seq_printf(m, "%s:%u [%s]%s %s \"",
572 dp->filename, dp->lineno,
573 iter->table->mod_name, dp->function,
574 ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf)));
575 seq_escape(m, dp->format, "\t\r\n\"");
576 seq_puts(m, "\"\n");
577
578 return 0;
579}
580
581/*
582 * Seq_ops stop method. Called at the end of each read()
583 * call from userspace. Drops ddebug_lock.
584 */
585static void ddebug_proc_stop(struct seq_file *m, void *p)
586{
587 if (verbose)
588 printk(KERN_INFO "%s: called m=%p p=%p\n",
589 __func__, m, p);
590 mutex_unlock(&ddebug_lock);
591}
592
593static const struct seq_operations ddebug_proc_seqops = {
594 .start = ddebug_proc_start,
595 .next = ddebug_proc_next,
596 .show = ddebug_proc_show,
597 .stop = ddebug_proc_stop
598};
599
600/*
601 * File_ops->open method for <debugfs>/dynamic_debug/control. Does the seq_file
602 * setup dance, and also creates an iterator to walk the _ddebugs.
603 * Note that we create a seq_file always, even for O_WRONLY files
604 * where it's not needed, as doing so simplifies the ->release method.
605 */
606static int ddebug_proc_open(struct inode *inode, struct file *file)
607{
608 struct ddebug_iter *iter;
609 int err;
610
611 if (verbose)
612 printk(KERN_INFO "%s: called\n", __func__);
613
614 iter = kzalloc(sizeof(*iter), GFP_KERNEL);
615 if (iter == NULL)
616 return -ENOMEM;
617
618 err = seq_open(file, &ddebug_proc_seqops);
619 if (err) {
620 kfree(iter);
621 return err;
622 }
623 ((struct seq_file *) file->private_data)->private = iter;
624 return 0;
625}
626
627static const struct file_operations ddebug_proc_fops = {
628 .owner = THIS_MODULE,
629 .open = ddebug_proc_open,
630 .read = seq_read,
631 .llseek = seq_lseek,
632 .release = seq_release_private,
633 .write = ddebug_proc_write
634};
635
636/*
637 * Allocate a new ddebug_table for the given module
638 * and add it to the global list.
639 */
640int ddebug_add_module(struct _ddebug *tab, unsigned int n,
641 const char *name)
642{
643 struct ddebug_table *dt;
644 char *new_name;
645
646 dt = kzalloc(sizeof(*dt), GFP_KERNEL);
647 if (dt == NULL)
648 return -ENOMEM;
649 new_name = kstrdup(name, GFP_KERNEL);
650 if (new_name == NULL) {
651 kfree(dt);
652 return -ENOMEM;
653 }
654 dt->mod_name = new_name;
655 dt->num_ddebugs = n;
656 dt->num_enabled = 0;
657 dt->ddebugs = tab;
658
659 mutex_lock(&ddebug_lock);
660 list_add_tail(&dt->link, &ddebug_tables);
661 mutex_unlock(&ddebug_lock);
662
663 if (verbose)
664 printk(KERN_INFO "%u debug prints in module %s\n",
665 n, dt->mod_name);
666 return 0;
667}
668EXPORT_SYMBOL_GPL(ddebug_add_module);
669
670static void ddebug_table_free(struct ddebug_table *dt)
671{
672 list_del_init(&dt->link);
673 kfree(dt->mod_name);
674 kfree(dt);
675}
676
677/*
678 * Called in response to a module being unloaded. Removes
679 * any ddebug_table's which point at the module.
680 */
681int ddebug_remove_module(char *mod_name)
682{
683 struct ddebug_table *dt, *nextdt;
684 int ret = -ENOENT;
685
686 if (verbose)
687 printk(KERN_INFO "%s: removing module \"%s\"\n",
688 __func__, mod_name);
689
690 mutex_lock(&ddebug_lock);
691 list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) {
692 if (!strcmp(dt->mod_name, mod_name)) {
693 ddebug_table_free(dt);
694 ret = 0;
695 }
696 }
697 mutex_unlock(&ddebug_lock);
698 return ret;
699}
700EXPORT_SYMBOL_GPL(ddebug_remove_module);
701
702static void ddebug_remove_all_tables(void)
703{
704 mutex_lock(&ddebug_lock);
705 while (!list_empty(&ddebug_tables)) {
706 struct ddebug_table *dt = list_entry(ddebug_tables.next,
707 struct ddebug_table,
708 link);
709 ddebug_table_free(dt);
710 }
711 mutex_unlock(&ddebug_lock);
712}
713
714static int __init dynamic_debug_init(void)
715{
716 struct dentry *dir, *file;
717 struct _ddebug *iter, *iter_start;
718 const char *modname = NULL;
719 int ret = 0;
720 int n = 0;
721
722 dir = debugfs_create_dir("dynamic_debug", NULL);
723 if (!dir)
724 return -ENOMEM;
725 file = debugfs_create_file("control", 0644, dir, NULL,
726 &ddebug_proc_fops);
727 if (!file) {
728 debugfs_remove(dir);
729 return -ENOMEM;
730 }
731 if (__start___verbose != __stop___verbose) {
732 iter = __start___verbose;
733 modname = iter->modname;
734 iter_start = iter;
735 for (; iter < __stop___verbose; iter++) {
736 if (strcmp(modname, iter->modname)) {
737 ret = ddebug_add_module(iter_start, n, modname);
738 if (ret)
739 goto out_free;
740 n = 0;
741 modname = iter->modname;
742 iter_start = iter;
743 }
744 n++;
745 }
746 ret = ddebug_add_module(iter_start, n, modname);
747 }
748out_free:
749 if (ret) {
750 ddebug_remove_all_tables();
751 debugfs_remove(dir);
752 debugfs_remove(file);
753 }
754 return 0;
755}
756module_init(dynamic_debug_init);
diff --git a/lib/dynamic_printk.c b/lib/dynamic_printk.c
deleted file mode 100644
index 165a19763dc9..000000000000
--- a/lib/dynamic_printk.c
+++ /dev/null
@@ -1,414 +0,0 @@
1/*
2 * lib/dynamic_printk.c
3 *
4 * make pr_debug()/dev_dbg() calls runtime configurable based upon their
5 * their source module.
6 *
7 * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
8 */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/uaccess.h>
13#include <linux/seq_file.h>
14#include <linux/debugfs.h>
15#include <linux/fs.h>
16
17extern struct mod_debug __start___verbose[];
18extern struct mod_debug __stop___verbose[];
19
20struct debug_name {
21 struct hlist_node hlist;
22 struct hlist_node hlist2;
23 int hash1;
24 int hash2;
25 char *name;
26 int enable;
27 int type;
28};
29
30static int nr_entries;
31static int num_enabled;
32int dynamic_enabled = DYNAMIC_ENABLED_NONE;
33static struct hlist_head module_table[DEBUG_HASH_TABLE_SIZE] =
34 { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
35static struct hlist_head module_table2[DEBUG_HASH_TABLE_SIZE] =
36 { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
37static DECLARE_MUTEX(debug_list_mutex);
38
39/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
40 * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
41 * use independent hash functions, to reduce the chance of false positives.
42 */
43long long dynamic_printk_enabled;
44EXPORT_SYMBOL_GPL(dynamic_printk_enabled);
45long long dynamic_printk_enabled2;
46EXPORT_SYMBOL_GPL(dynamic_printk_enabled2);
47
48/* returns the debug module pointer. */
49static struct debug_name *find_debug_module(char *module_name)
50{
51 int i;
52 struct hlist_head *head;
53 struct hlist_node *node;
54 struct debug_name *element;
55
56 element = NULL;
57 for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
58 head = &module_table[i];
59 hlist_for_each_entry_rcu(element, node, head, hlist)
60 if (!strcmp(element->name, module_name))
61 return element;
62 }
63 return NULL;
64}
65
66/* returns the debug module pointer. */
67static struct debug_name *find_debug_module_hash(char *module_name, int hash)
68{
69 struct hlist_head *head;
70 struct hlist_node *node;
71 struct debug_name *element;
72
73 element = NULL;
74 head = &module_table[hash];
75 hlist_for_each_entry_rcu(element, node, head, hlist)
76 if (!strcmp(element->name, module_name))
77 return element;
78 return NULL;
79}
80
81/* caller must hold mutex*/
82static int __add_debug_module(char *mod_name, int hash, int hash2)
83{
84 struct debug_name *new;
85 char *module_name;
86 int ret = 0;
87
88 if (find_debug_module(mod_name)) {
89 ret = -EINVAL;
90 goto out;
91 }
92 module_name = kmalloc(strlen(mod_name) + 1, GFP_KERNEL);
93 if (!module_name) {
94 ret = -ENOMEM;
95 goto out;
96 }
97 module_name = strcpy(module_name, mod_name);
98 module_name[strlen(mod_name)] = '\0';
99 new = kzalloc(sizeof(struct debug_name), GFP_KERNEL);
100 if (!new) {
101 kfree(module_name);
102 ret = -ENOMEM;
103 goto out;
104 }
105 INIT_HLIST_NODE(&new->hlist);
106 INIT_HLIST_NODE(&new->hlist2);
107 new->name = module_name;
108 new->hash1 = hash;
109 new->hash2 = hash2;
110 hlist_add_head_rcu(&new->hlist, &module_table[hash]);
111 hlist_add_head_rcu(&new->hlist2, &module_table2[hash2]);
112 nr_entries++;
113out:
114 return ret;
115}
116
117int unregister_dynamic_debug_module(char *mod_name)
118{
119 struct debug_name *element;
120 int ret = 0;
121
122 down(&debug_list_mutex);
123 element = find_debug_module(mod_name);
124 if (!element) {
125 ret = -EINVAL;
126 goto out;
127 }
128 hlist_del_rcu(&element->hlist);
129 hlist_del_rcu(&element->hlist2);
130 synchronize_rcu();
131 kfree(element->name);
132 if (element->enable)
133 num_enabled--;
134 kfree(element);
135 nr_entries--;
136out:
137 up(&debug_list_mutex);
138 return ret;
139}
140EXPORT_SYMBOL_GPL(unregister_dynamic_debug_module);
141
142int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
143 char *flags, int hash, int hash2)
144{
145 struct debug_name *elem;
146 int ret = 0;
147
148 down(&debug_list_mutex);
149 elem = find_debug_module(mod_name);
150 if (!elem) {
151 if (__add_debug_module(mod_name, hash, hash2))
152 goto out;
153 elem = find_debug_module(mod_name);
154 if (dynamic_enabled == DYNAMIC_ENABLED_ALL &&
155 !strcmp(mod_name, share_name)) {
156 elem->enable = true;
157 num_enabled++;
158 }
159 }
160 elem->type |= type;
161out:
162 up(&debug_list_mutex);
163 return ret;
164}
165EXPORT_SYMBOL_GPL(register_dynamic_debug_module);
166
167int __dynamic_dbg_enabled_helper(char *mod_name, int type, int value, int hash)
168{
169 struct debug_name *elem;
170 int ret = 0;
171
172 if (dynamic_enabled == DYNAMIC_ENABLED_ALL)
173 return 1;
174 rcu_read_lock();
175 elem = find_debug_module_hash(mod_name, hash);
176 if (elem && elem->enable)
177 ret = 1;
178 rcu_read_unlock();
179 return ret;
180}
181EXPORT_SYMBOL_GPL(__dynamic_dbg_enabled_helper);
182
183static void set_all(bool enable)
184{
185 struct debug_name *e;
186 struct hlist_node *node;
187 int i;
188 long long enable_mask;
189
190 for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
191 if (module_table[i].first != NULL) {
192 hlist_for_each_entry(e, node, &module_table[i], hlist) {
193 e->enable = enable;
194 }
195 }
196 }
197 if (enable)
198 enable_mask = ULLONG_MAX;
199 else
200 enable_mask = 0;
201 dynamic_printk_enabled = enable_mask;
202 dynamic_printk_enabled2 = enable_mask;
203}
204
205static int disabled_hash(int i, bool first_table)
206{
207 struct debug_name *e;
208 struct hlist_node *node;
209
210 if (first_table) {
211 hlist_for_each_entry(e, node, &module_table[i], hlist) {
212 if (e->enable)
213 return 0;
214 }
215 } else {
216 hlist_for_each_entry(e, node, &module_table2[i], hlist2) {
217 if (e->enable)
218 return 0;
219 }
220 }
221 return 1;
222}
223
224static ssize_t pr_debug_write(struct file *file, const char __user *buf,
225 size_t length, loff_t *ppos)
226{
227 char *buffer, *s, *value_str, *setting_str;
228 int err, value;
229 struct debug_name *elem = NULL;
230 int all = 0;
231
232 if (length > PAGE_SIZE || length < 0)
233 return -EINVAL;
234
235 buffer = (char *)__get_free_page(GFP_KERNEL);
236 if (!buffer)
237 return -ENOMEM;
238
239 err = -EFAULT;
240 if (copy_from_user(buffer, buf, length))
241 goto out;
242
243 err = -EINVAL;
244 if (length < PAGE_SIZE)
245 buffer[length] = '\0';
246 else if (buffer[PAGE_SIZE-1])
247 goto out;
248
249 err = -EINVAL;
250 down(&debug_list_mutex);
251
252 if (strncmp("set", buffer, 3))
253 goto out_up;
254 s = buffer + 3;
255 setting_str = strsep(&s, "=");
256 if (s == NULL)
257 goto out_up;
258 setting_str = strstrip(setting_str);
259 value_str = strsep(&s, " ");
260 if (s == NULL)
261 goto out_up;
262 s = strstrip(s);
263 if (!strncmp(s, "all", 3))
264 all = 1;
265 else
266 elem = find_debug_module(s);
267 if (!strncmp(setting_str, "enable", 6)) {
268 value = !!simple_strtol(value_str, NULL, 10);
269 if (all) {
270 if (value) {
271 set_all(true);
272 num_enabled = nr_entries;
273 dynamic_enabled = DYNAMIC_ENABLED_ALL;
274 } else {
275 set_all(false);
276 num_enabled = 0;
277 dynamic_enabled = DYNAMIC_ENABLED_NONE;
278 }
279 err = 0;
280 } else if (elem) {
281 if (value && (elem->enable == 0)) {
282 dynamic_printk_enabled |= (1LL << elem->hash1);
283 dynamic_printk_enabled2 |= (1LL << elem->hash2);
284 elem->enable = 1;
285 num_enabled++;
286 dynamic_enabled = DYNAMIC_ENABLED_SOME;
287 err = 0;
288 printk(KERN_DEBUG
289 "debugging enabled for module %s\n",
290 elem->name);
291 } else if (!value && (elem->enable == 1)) {
292 elem->enable = 0;
293 num_enabled--;
294 if (disabled_hash(elem->hash1, true))
295 dynamic_printk_enabled &=
296 ~(1LL << elem->hash1);
297 if (disabled_hash(elem->hash2, false))
298 dynamic_printk_enabled2 &=
299 ~(1LL << elem->hash2);
300 if (num_enabled)
301 dynamic_enabled = DYNAMIC_ENABLED_SOME;
302 else
303 dynamic_enabled = DYNAMIC_ENABLED_NONE;
304 err = 0;
305 printk(KERN_DEBUG
306 "debugging disabled for module %s\n",
307 elem->name);
308 }
309 }
310 }
311 if (!err)
312 err = length;
313out_up:
314 up(&debug_list_mutex);
315out:
316 free_page((unsigned long)buffer);
317 return err;
318}
319
320static void *pr_debug_seq_start(struct seq_file *f, loff_t *pos)
321{
322 return (*pos < DEBUG_HASH_TABLE_SIZE) ? pos : NULL;
323}
324
325static void *pr_debug_seq_next(struct seq_file *s, void *v, loff_t *pos)
326{
327 (*pos)++;
328 if (*pos >= DEBUG_HASH_TABLE_SIZE)
329 return NULL;
330 return pos;
331}
332
333static void pr_debug_seq_stop(struct seq_file *s, void *v)
334{
335 /* Nothing to do */
336}
337
338static int pr_debug_seq_show(struct seq_file *s, void *v)
339{
340 struct hlist_head *head;
341 struct hlist_node *node;
342 struct debug_name *elem;
343 unsigned int i = *(loff_t *) v;
344
345 rcu_read_lock();
346 head = &module_table[i];
347 hlist_for_each_entry_rcu(elem, node, head, hlist) {
348 seq_printf(s, "%s enabled=%d", elem->name, elem->enable);
349 seq_printf(s, "\n");
350 }
351 rcu_read_unlock();
352 return 0;
353}
354
355static struct seq_operations pr_debug_seq_ops = {
356 .start = pr_debug_seq_start,
357 .next = pr_debug_seq_next,
358 .stop = pr_debug_seq_stop,
359 .show = pr_debug_seq_show
360};
361
362static int pr_debug_open(struct inode *inode, struct file *filp)
363{
364 return seq_open(filp, &pr_debug_seq_ops);
365}
366
367static const struct file_operations pr_debug_operations = {
368 .open = pr_debug_open,
369 .read = seq_read,
370 .write = pr_debug_write,
371 .llseek = seq_lseek,
372 .release = seq_release,
373};
374
375static int __init dynamic_printk_init(void)
376{
377 struct dentry *dir, *file;
378 struct mod_debug *iter;
379 unsigned long value;
380
381 dir = debugfs_create_dir("dynamic_printk", NULL);
382 if (!dir)
383 return -ENOMEM;
384 file = debugfs_create_file("modules", 0644, dir, NULL,
385 &pr_debug_operations);
386 if (!file) {
387 debugfs_remove(dir);
388 return -ENOMEM;
389 }
390 for (value = (unsigned long)__start___verbose;
391 value < (unsigned long)__stop___verbose;
392 value += sizeof(struct mod_debug)) {
393 iter = (struct mod_debug *)value;
394 register_dynamic_debug_module(iter->modname,
395 iter->type,
396 iter->logical_modname,
397 iter->flag_names, iter->hash, iter->hash2);
398 }
399 if (dynamic_enabled == DYNAMIC_ENABLED_ALL)
400 set_all(true);
401 return 0;
402}
403module_init(dynamic_printk_init);
404/* may want to move this earlier so we can get traces as early as possible */
405
406static int __init dynamic_printk_setup(char *str)
407{
408 if (str)
409 return -ENOENT;
410 dynamic_enabled = DYNAMIC_ENABLED_ALL;
411 return 0;
412}
413/* Use early_param(), so we can get debug output as early as possible */
414early_param("dynamic_printk", dynamic_printk_setup);
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 9e169ef2e854..12bd09dbd36c 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -66,7 +66,7 @@ void
66 struct nf_conntrack_expect *exp) __read_mostly; 66 struct nf_conntrack_expect *exp) __read_mostly;
67EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn); 67EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
68 68
69#if defined(DEBUG) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG) 69#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
70/* PptpControlMessageType names */ 70/* PptpControlMessageType names */
71const char *const pptp_msg_name[] = { 71const char *const pptp_msg_name[] = {
72 "UNKNOWN_MESSAGE", 72 "UNKNOWN_MESSAGE",
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index e06365775bdf..c18fa150b6fe 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -97,7 +97,7 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\
97 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") 97 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
98 98
99#hash values 99#hash values
100ifdef CONFIG_DYNAMIC_PRINTK_DEBUG 100ifdef CONFIG_DYNAMIC_DEBUG
101debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\ 101debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
102 -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))" 102 -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
103else 103else