]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/driver-core-basic-infrastructure-for-per-module-dynamic-debug-messages.patch
Changed checkfs to auto reboot after correctable fsck fixes.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / driver-core-basic-infrastructure-for-per-module-dynamic-debug-messages.patch
CommitLineData
00e5a55c
BS
1From jbaron@redhat.com Tue Aug 12 17:09:39 2008
2From: Jason Baron <jbaron@redhat.com>
3Date: Tue, 12 Aug 2008 16:46:19 -0400
4Subject: driver core: basic infrastructure for per-module dynamic debug messages
5To: Greg KH <greg@kroah.com>
6Cc: Randy Dunlap <randy.dunlap@oracle.com>, linux-kernel@vger.kernel.org, akpm@linux-foundation.org, joe@perches.com, nick@nick-andrew.net
7Message-ID: <20080812204619.GE6056@redhat.com>
8Patch-mainline: 2.6.28
9
10Base infrastructure to enable per-module debug messages.
11
12I've introduced CONFIG_DYNAMIC_PRINTK_DEBUG, which when enabled centralizes
13control of debugging statements on a per-module basis in one /proc file,
14currently, <debugfs>/dynamic_printk/modules. When, CONFIG_DYNAMIC_PRINTK_DEBUG,
15is not set, debugging statements can still be enabled as before, often by
16defining 'DEBUG' for the proper compilation unit. Thus, this patch set has no
17affect when CONFIG_DYNAMIC_PRINTK_DEBUG is not set.
18
19The infrastructure currently ties into all pr_debug() and dev_dbg() calls. That
20is, if CONFIG_DYNAMIC_PRINTK_DEBUG is set, all pr_debug() and dev_dbg() calls
21can be dynamically enabled/disabled on a per-module basis.
22
23Future plans include extending this functionality to subsystems, that define
24their own debug levels and flags.
25
26Usage:
27
28Dynamic debugging is controlled by the debugfs file,
29<debugfs>/dynamic_printk/modules. This file contains a list of the modules that
30can be enabled. The format of the file is as follows:
31
32 <module_name> <enabled=0/1>
33 .
34 .
35 .
36
37 <module_name> : Name of the module in which the debug call resides
38 <enabled=0/1> : whether the messages are enabled or not
39
40For example:
41
42 snd_hda_intel enabled=0
43 fixup enabled=1
44 driver enabled=0
45
46Enable a module:
47
48 $echo "set enabled=1 <module_name>" > dynamic_printk/modules
49
50Disable a module:
51
52 $echo "set enabled=0 <module_name>" > dynamic_printk/modules
53
54Enable all modules:
55
56 $echo "set enabled=1 all" > dynamic_printk/modules
57
58Disable all modules:
59
60 $echo "set enabled=0 all" > dynamic_printk/modules
61
62Finally, passing "dynamic_printk" at the command line enables
63debugging for all modules. This mode can be turned off via the above
64disable command.
65
66[gkh: minor cleanups and tweaks to make the build work quietly]
67
68Signed-off-by: Jason Baron <jbaron@redhat.com>
69Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
70
71
72---
73 Documentation/kernel-parameters.txt | 5
74 include/asm-generic/vmlinux.lds.h | 10
75 include/linux/device.h | 6
76 include/linux/dynamic_printk.h | 93 ++++++++
77 include/linux/kernel.h | 7
78 include/linux/module.h | 1
79 kernel/module.c | 31 ++
80 lib/Kconfig.debug | 55 ++++
81 lib/Makefile | 2
82 lib/dynamic_printk.c | 418 ++++++++++++++++++++++++++++++++++++
83 net/netfilter/nf_conntrack_pptp.c | 2
84 scripts/Makefile.lib | 11
85 scripts/basic/Makefile | 2
86 scripts/basic/hash.c | 64 +++++
87 14 files changed, 700 insertions(+), 7 deletions(-)
88
89--- a/Documentation/kernel-parameters.txt
90+++ b/Documentation/kernel-parameters.txt
91@@ -1735,6 +1735,11 @@ and is between 256 and 4096 characters.
92 autoconfiguration.
93 Ranges are in pairs (memory base and size).
94
95+ dynamic_printk
96+ Enables pr_debug()/dev_dbg() calls if
97+ CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also
98+ be switched on/off via <debugfs>/dynamic_printk/modules
99+
100 print-fatal-signals=
101 [KNL] debug: print fatal signals
102 print-fatal-signals=1: print segfault info to
103--- a/include/asm-generic/vmlinux.lds.h
104+++ b/include/asm-generic/vmlinux.lds.h
105@@ -268,7 +268,15 @@
106 CPU_DISCARD(init.data) \
107 CPU_DISCARD(init.rodata) \
108 MEM_DISCARD(init.data) \
109- MEM_DISCARD(init.rodata)
110+ MEM_DISCARD(init.rodata) \
111+ /* implement dynamic printk debug */ \
112+ VMLINUX_SYMBOL(__start___verbose_strings) = .; \
113+ *(__verbose_strings) \
114+ VMLINUX_SYMBOL(__stop___verbose_strings) = .; \
115+ . = ALIGN(8); \
116+ VMLINUX_SYMBOL(__start___verbose) = .; \
117+ *(__verbose) \
118+ VMLINUX_SYMBOL(__stop___verbose) = .;
119
120 #define INIT_TEXT \
121 *(.init.text) \
122--- a/include/linux/device.h
123+++ b/include/linux/device.h
124@@ -553,7 +553,11 @@ int printk_dev_hash(const char *, const
125 #define dev_info(dev, format, arg...) \
126 dev_printk_hash(KERN_INFO , dev , format , ## arg)
127
128-#ifdef DEBUG
129+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
130+#define dev_dbg(dev, format, ...) do { \
131+ dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
132+ } while (0)
133+#elif defined(DEBUG)
134 #define dev_dbg(dev, format, arg...) \
135 dev_printk(KERN_DEBUG , dev , format , ## arg)
136 #else
137--- /dev/null
138+++ b/include/linux/dynamic_printk.h
139@@ -0,0 +1,93 @@
140+#ifndef _DYNAMIC_PRINTK_H
141+#define _DYNAMIC_PRINTK_H
142+
143+#define DYNAMIC_DEBUG_HASH_BITS 6
144+#define DEBUG_HASH_TABLE_SIZE (1 << DYNAMIC_DEBUG_HASH_BITS)
145+
146+#define TYPE_BOOLEAN 1
147+
148+#define DYNAMIC_ENABLED_ALL 0
149+#define DYNAMIC_ENABLED_NONE 1
150+#define DYNAMIC_ENABLED_SOME 2
151+
152+extern int dynamic_enabled;
153+
154+/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
155+ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
156+ * use independent hash functions, to reduce the chance of false positives.
157+ */
158+extern long long dynamic_printk_enabled;
159+extern long long dynamic_printk_enabled2;
160+
161+struct mod_debug {
162+ char *modname;
163+ char *logical_modname;
164+ char *flag_names;
165+ int type;
166+ int hash;
167+ int hash2;
168+} __attribute__((aligned(8)));
169+
170+int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
171+ char *flags, int hash, int hash2);
172+
173+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
174+extern int unregister_dynamic_debug_module(char *mod_name);
175+extern int __dynamic_dbg_enabled_helper(char *modname, int type,
176+ int value, int hash);
177+
178+#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ \
179+ int __ret = 0; \
180+ if (unlikely((dynamic_printk_enabled & (1LL << DEBUG_HASH)) && \
181+ (dynamic_printk_enabled2 & (1LL << DEBUG_HASH2)))) \
182+ __ret = __dynamic_dbg_enabled_helper(module, type, \
183+ value, hash);\
184+ __ret; })
185+
186+#define dynamic_pr_debug(fmt, ...) do { \
187+ static char mod_name[] \
188+ __attribute__((section("__verbose_strings"))) \
189+ = KBUILD_MODNAME; \
190+ static struct mod_debug descriptor \
191+ __used \
192+ __attribute__((section("__verbose"), aligned(8))) = \
193+ { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
194+ if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
195+ 0, 0, DEBUG_HASH)) \
196+ printk(KERN_DEBUG KBUILD_MODNAME ":" fmt, \
197+ ##__VA_ARGS__); \
198+ } while (0)
199+
200+#define dynamic_dev_dbg(dev, format, ...) do { \
201+ static char mod_name[] \
202+ __attribute__((section("__verbose_strings"))) \
203+ = KBUILD_MODNAME; \
204+ static struct mod_debug descriptor \
205+ __used \
206+ __attribute__((section("__verbose"), aligned(8))) = \
207+ { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
208+ if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
209+ 0, 0, DEBUG_HASH)) \
210+ dev_printk(KERN_DEBUG, dev, \
211+ KBUILD_MODNAME ": " format, \
212+ ##__VA_ARGS__); \
213+ } while (0)
214+
215+#else
216+
217+static inline int unregister_dynamic_debug_module(const char *mod_name)
218+{
219+ return 0;
220+}
221+static inline int __dynamic_dbg_enabled_helper(char *modname, int type,
222+ int value, int hash)
223+{
224+ return 0;
225+}
226+
227+#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ 0; })
228+#define dynamic_pr_debug(fmt, ...) do { } while (0)
229+#define dynamic_dev_dbg(dev, format, ...) do { } while (0)
230+#endif
231+
232+#endif
233--- a/include/linux/kernel.h
234+++ b/include/linux/kernel.h
235@@ -16,6 +16,7 @@
236 #include <linux/log2.h>
237 #include <linux/typecheck.h>
238 #include <linux/ratelimit.h>
239+#include <linux/dynamic_printk.h>
240 #include <asm/byteorder.h>
241 #include <asm/bug.h>
242
243@@ -331,8 +332,12 @@ int printk_hash(const char *, const char
244 #define pr_info(fmt, arg...) \
245 pr_printk_hash(KERN_INFO, fmt, ##arg)
246
247-#ifdef DEBUG
248 /* If you are writing a driver, please use dev_dbg instead */
249+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
250+#define pr_debug(fmt, ...) do { \
251+ dynamic_pr_debug(fmt, ##__VA_ARGS__); \
252+ } while (0)
253+#elif defined(DEBUG)
254 #define pr_debug(fmt, arg...) \
255 pr_printk(KERN_DEBUG, fmt, ##arg)
256 #else
257--- a/include/linux/module.h
258+++ b/include/linux/module.h
259@@ -345,7 +345,6 @@ struct module
260 /* Reference counts */
261 struct module_ref ref[NR_CPUS];
262 #endif
263-
264 };
265 #ifndef MODULE_ARCH_INIT
266 #define MODULE_ARCH_INIT {}
267--- a/kernel/module.c
268+++ b/kernel/module.c
269@@ -798,6 +798,7 @@ SYSCALL_DEFINE2(delete_module, const cha
270 mutex_lock(&module_mutex);
271 /* Store the name of the last unloaded module for diagnostic purposes */
272 strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
273+ unregister_dynamic_debug_module(mod->name);
274 free_module(mod);
275
276 out:
277@@ -1823,6 +1824,33 @@ static inline void add_kallsyms(struct m
278 }
279 #endif /* CONFIG_KALLSYMS */
280
281+#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
282+static void dynamic_printk_setup(Elf_Shdr *sechdrs, unsigned int verboseindex)
283+{
284+ struct mod_debug *debug_info;
285+ unsigned long pos, end;
286+ unsigned int num_verbose;
287+
288+ pos = sechdrs[verboseindex].sh_addr;
289+ num_verbose = sechdrs[verboseindex].sh_size /
290+ sizeof(struct mod_debug);
291+ end = pos + (num_verbose * sizeof(struct mod_debug));
292+
293+ for (; pos < end; pos += sizeof(struct mod_debug)) {
294+ debug_info = (struct mod_debug *)pos;
295+ register_dynamic_debug_module(debug_info->modname,
296+ debug_info->type, debug_info->logical_modname,
297+ debug_info->flag_names, debug_info->hash,
298+ debug_info->hash2);
299+ }
300+}
301+#else
302+static inline void dynamic_printk_setup(Elf_Shdr *sechdrs,
303+ unsigned int verboseindex)
304+{
305+}
306+#endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */
307+
308 static void *module_alloc_update_bounds(unsigned long size)
309 {
310 void *ret = module_alloc(size);
311@@ -1871,6 +1899,7 @@ static noinline struct module *load_modu
312 #endif
313 unsigned int markersindex;
314 unsigned int markersstringsindex;
315+ unsigned int verboseindex;
316 struct module *mod;
317 long err = 0;
318 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
319@@ -2157,6 +2186,7 @@ static noinline struct module *load_modu
320 markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
321 markersstringsindex = find_sec(hdr, sechdrs, secstrings,
322 "__markers_strings");
323+ verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose");
324
325 /* Now do relocations. */
326 for (i = 1; i < hdr->e_shnum; i++) {
327@@ -2207,6 +2237,7 @@ static noinline struct module *load_modu
328 marker_update_probe_range(mod->markers,
329 mod->markers + mod->num_markers);
330 #endif
331+ dynamic_printk_setup(sechdrs, verboseindex);
332 err = module_finalize(hdr, sechdrs, mod);
333 if (err < 0)
334 goto cleanup;
335--- /dev/null
336+++ b/lib/dynamic_printk.c
337@@ -0,0 +1,418 @@
338+/*
339+ * lib/dynamic_printk.c
340+ *
341+ * make pr_debug()/dev_dbg() calls runtime configurable based upon their
342+ * their source module.
343+ *
344+ * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
345+ */
346+
347+#include <linux/kernel.h>
348+#include <linux/module.h>
349+#include <linux/uaccess.h>
350+#include <linux/seq_file.h>
351+#include <linux/debugfs.h>
352+#include <linux/fs.h>
353+
354+extern struct mod_debug __start___verbose[];
355+extern struct mod_debug __stop___verbose[];
356+
357+struct debug_name {
358+ struct hlist_node hlist;
359+ struct hlist_node hlist2;
360+ int hash1;
361+ int hash2;
362+ char *name;
363+ int enable;
364+ int type;
365+};
366+
367+static int nr_entries;
368+static int num_enabled;
369+int dynamic_enabled = DYNAMIC_ENABLED_NONE;
370+static struct hlist_head module_table[DEBUG_HASH_TABLE_SIZE] =
371+ { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
372+static struct hlist_head module_table2[DEBUG_HASH_TABLE_SIZE] =
373+ { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
374+static DECLARE_MUTEX(debug_list_mutex);
375+
376+/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
377+ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
378+ * use independent hash functions, to reduce the chance of false positives.
379+ */
380+long long dynamic_printk_enabled;
381+EXPORT_SYMBOL_GPL(dynamic_printk_enabled);
382+long long dynamic_printk_enabled2;
383+EXPORT_SYMBOL_GPL(dynamic_printk_enabled2);
384+
385+/* returns the debug module pointer. */
386+static struct debug_name *find_debug_module(char *module_name)
387+{
388+ int i;
389+ struct hlist_head *head;
390+ struct hlist_node *node;
391+ struct debug_name *element;
392+
393+ element = NULL;
394+ for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
395+ head = &module_table[i];
396+ hlist_for_each_entry_rcu(element, node, head, hlist)
397+ if (!strcmp(element->name, module_name))
398+ return element;
399+ }
400+ return NULL;
401+}
402+
403+/* returns the debug module pointer. */
404+static struct debug_name *find_debug_module_hash(char *module_name, int hash)
405+{
406+ struct hlist_head *head;
407+ struct hlist_node *node;
408+ struct debug_name *element;
409+
410+ element = NULL;
411+ head = &module_table[hash];
412+ hlist_for_each_entry_rcu(element, node, head, hlist)
413+ if (!strcmp(element->name, module_name))
414+ return element;
415+ return NULL;
416+}
417+
418+/* caller must hold mutex*/
419+static int __add_debug_module(char *mod_name, int hash, int hash2)
420+{
421+ struct debug_name *new;
422+ char *module_name;
423+ int ret = 0;
424+
425+ if (find_debug_module(mod_name)) {
426+ ret = -EINVAL;
427+ goto out;
428+ }
429+ module_name = kmalloc(strlen(mod_name) + 1, GFP_KERNEL);
430+ if (!module_name) {
431+ ret = -ENOMEM;
432+ goto out;
433+ }
434+ module_name = strcpy(module_name, mod_name);
435+ module_name[strlen(mod_name)] = '\0';
436+ new = kzalloc(sizeof(struct debug_name), GFP_KERNEL);
437+ if (!new) {
438+ kfree(module_name);
439+ ret = -ENOMEM;
440+ goto out;
441+ }
442+ INIT_HLIST_NODE(&new->hlist);
443+ INIT_HLIST_NODE(&new->hlist2);
444+ new->name = module_name;
445+ new->hash1 = hash;
446+ new->hash2 = hash2;
447+ hlist_add_head_rcu(&new->hlist, &module_table[hash]);
448+ hlist_add_head_rcu(&new->hlist2, &module_table2[hash2]);
449+ nr_entries++;
450+out:
451+ return ret;
452+}
453+
454+int unregister_dynamic_debug_module(char *mod_name)
455+{
456+ struct debug_name *element;
457+ int ret = 0;
458+
459+ down(&debug_list_mutex);
460+ element = find_debug_module(mod_name);
461+ if (!element) {
462+ ret = -EINVAL;
463+ goto out;
464+ }
465+ hlist_del_rcu(&element->hlist);
466+ hlist_del_rcu(&element->hlist2);
467+ synchronize_rcu();
468+ kfree(element->name);
469+ if (element->enable)
470+ num_enabled--;
471+ kfree(element);
472+ nr_entries--;
473+out:
474+ up(&debug_list_mutex);
475+ return 0;
476+}
477+EXPORT_SYMBOL_GPL(unregister_dynamic_debug_module);
478+
479+int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
480+ char *flags, int hash, int hash2)
481+{
482+ struct debug_name *elem;
483+ int ret = 0;
484+
485+ down(&debug_list_mutex);
486+ elem = find_debug_module(mod_name);
487+ if (!elem) {
488+ if (__add_debug_module(mod_name, hash, hash2))
489+ goto out;
490+ elem = find_debug_module(mod_name);
491+ if (dynamic_enabled == DYNAMIC_ENABLED_ALL &&
492+ !strcmp(mod_name, share_name)) {
493+ elem->enable = true;
494+ num_enabled++;
495+ }
496+ }
497+ elem->type |= type;
498+out:
499+ up(&debug_list_mutex);
500+ return ret;
501+}
502+EXPORT_SYMBOL_GPL(register_dynamic_debug_module);
503+
504+int __dynamic_dbg_enabled_helper(char *mod_name, int type, int value, int hash)
505+{
506+ struct debug_name *elem;
507+ int ret = 0;
508+
509+ if (dynamic_enabled == DYNAMIC_ENABLED_ALL)
510+ return 1;
511+ rcu_read_lock();
512+ elem = find_debug_module_hash(mod_name, hash);
513+ if (elem && elem->enable)
514+ ret = 1;
515+ rcu_read_unlock();
516+ return ret;
517+}
518+EXPORT_SYMBOL_GPL(__dynamic_dbg_enabled_helper);
519+
520+static void set_all(bool enable)
521+{
522+ struct debug_name *e;
523+ struct hlist_node *node;
524+ int i;
525+ long long enable_mask;
526+
527+ for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
528+ if (module_table[i].first != NULL) {
529+ hlist_for_each_entry(e, node, &module_table[i], hlist) {
530+ e->enable = enable;
531+ }
532+ }
533+ }
534+ if (enable)
535+ enable_mask = ULLONG_MAX;
536+ else
537+ enable_mask = 0;
538+ dynamic_printk_enabled = enable_mask;
539+ dynamic_printk_enabled2 = enable_mask;
540+}
541+
542+static int disabled_hash(int i, bool first_table)
543+{
544+ struct debug_name *e;
545+ struct hlist_node *node;
546+
547+ if (first_table) {
548+ hlist_for_each_entry(e, node, &module_table[i], hlist) {
549+ if (e->enable)
550+ return 0;
551+ }
552+ } else {
553+ hlist_for_each_entry(e, node, &module_table2[i], hlist2) {
554+ if (e->enable)
555+ return 0;
556+ }
557+ }
558+ return 1;
559+}
560+
561+static ssize_t pr_debug_write(struct file *file, const char __user *buf,
562+ size_t length, loff_t *ppos)
563+{
564+ char *buffer, *s, *value_str, *setting_str;
565+ int err, value;
566+ struct debug_name *elem = NULL;
567+ int all = 0;
568+
569+ if (length > PAGE_SIZE || length < 0)
570+ return -EINVAL;
571+
572+ buffer = (char *)__get_free_page(GFP_KERNEL);
573+ if (!buffer)
574+ return -ENOMEM;
575+
576+ err = -EFAULT;
577+ if (copy_from_user(buffer, buf, length))
578+ goto out;
579+
580+ err = -EINVAL;
581+ if (length < PAGE_SIZE)
582+ buffer[length] = '\0';
583+ else if (buffer[PAGE_SIZE-1])
584+ goto out;
585+
586+ err = -EINVAL;
587+ down(&debug_list_mutex);
588+
589+ if (strncmp("set", buffer, 3))
590+ goto out_up;
591+ s = buffer + 3;
592+ setting_str = strsep(&s, "=");
593+ if (s == NULL)
594+ goto out_up;
595+ setting_str = strstrip(setting_str);
596+ value_str = strsep(&s, " ");
597+ if (s == NULL)
598+ goto out_up;
599+ s = strstrip(s);
600+ if (!strncmp(s, "all", 3))
601+ all = 1;
602+ else
603+ elem = find_debug_module(s);
604+ if (!strncmp(setting_str, "enable", 6)) {
605+ value = !!simple_strtol(value_str, NULL, 10);
606+ if (all) {
607+ if (value) {
608+ set_all(true);
609+ num_enabled = nr_entries;
610+ dynamic_enabled = DYNAMIC_ENABLED_ALL;
611+ } else {
612+ set_all(false);
613+ num_enabled = 0;
614+ dynamic_enabled = DYNAMIC_ENABLED_NONE;
615+ }
616+ err = 0;
617+ } else {
618+ if (elem) {
619+ if (value && (elem->enable == 0)) {
620+ dynamic_printk_enabled |=
621+ (1LL << elem->hash1);
622+ dynamic_printk_enabled2 |=
623+ (1LL << elem->hash2);
624+ elem->enable = 1;
625+ num_enabled++;
626+ dynamic_enabled = DYNAMIC_ENABLED_SOME;
627+ err = 0;
628+ printk(KERN_DEBUG
629+ "debugging enabled for module %s",
630+ elem->name);
631+ } else if (!value && (elem->enable == 1)) {
632+ elem->enable = 0;
633+ num_enabled--;
634+ if (disabled_hash(elem->hash1, true))
635+ dynamic_printk_enabled &=
636+ ~(1LL << elem->hash1);
637+ if (disabled_hash(elem->hash2, false))
638+ dynamic_printk_enabled2 &=
639+ ~(1LL << elem->hash2);
640+ if (num_enabled)
641+ dynamic_enabled =
642+ DYNAMIC_ENABLED_SOME;
643+ else
644+ dynamic_enabled =
645+ DYNAMIC_ENABLED_NONE;
646+ err = 0;
647+ printk(KERN_DEBUG
648+ "debugging disabled for module "
649+ "%s", elem->name);
650+ }
651+ }
652+ }
653+ }
654+ if (!err)
655+ err = length;
656+out_up:
657+ up(&debug_list_mutex);
658+out:
659+ free_page((unsigned long)buffer);
660+ return err;
661+}
662+
663+static void *pr_debug_seq_start(struct seq_file *f, loff_t *pos)
664+{
665+ return (*pos < DEBUG_HASH_TABLE_SIZE) ? pos : NULL;
666+}
667+
668+static void *pr_debug_seq_next(struct seq_file *s, void *v, loff_t *pos)
669+{
670+ (*pos)++;
671+ if (*pos >= DEBUG_HASH_TABLE_SIZE)
672+ return NULL;
673+ return pos;
674+}
675+
676+static void pr_debug_seq_stop(struct seq_file *s, void *v)
677+{
678+ /* Nothing to do */
679+}
680+
681+static int pr_debug_seq_show(struct seq_file *s, void *v)
682+{
683+ struct hlist_head *head;
684+ struct hlist_node *node;
685+ struct debug_name *elem;
686+ unsigned int i = *(loff_t *) v;
687+
688+ rcu_read_lock();
689+ head = &module_table[i];
690+ hlist_for_each_entry_rcu(elem, node, head, hlist) {
691+ seq_printf(s, "%s enabled=%d", elem->name, elem->enable);
692+ seq_printf(s, "\n");
693+ }
694+ rcu_read_unlock();
695+ return 0;
696+}
697+
698+static struct seq_operations pr_debug_seq_ops = {
699+ .start = pr_debug_seq_start,
700+ .next = pr_debug_seq_next,
701+ .stop = pr_debug_seq_stop,
702+ .show = pr_debug_seq_show
703+};
704+
705+static int pr_debug_open(struct inode *inode, struct file *filp)
706+{
707+ return seq_open(filp, &pr_debug_seq_ops);
708+}
709+
710+static const struct file_operations pr_debug_operations = {
711+ .open = pr_debug_open,
712+ .read = seq_read,
713+ .write = pr_debug_write,
714+ .llseek = seq_lseek,
715+ .release = seq_release,
716+};
717+
718+static int __init dynamic_printk_init(void)
719+{
720+ struct dentry *dir, *file;
721+ struct mod_debug *iter;
722+ unsigned long value;
723+
724+ dir = debugfs_create_dir("dynamic_printk", NULL);
725+ if (!dir)
726+ return -ENOMEM;
727+ file = debugfs_create_file("modules", 0644, dir, NULL,
728+ &pr_debug_operations);
729+ if (!file) {
730+ debugfs_remove(dir);
731+ return -ENOMEM;
732+ }
733+ for (value = (unsigned long)__start___verbose;
734+ value < (unsigned long)__stop___verbose;
735+ value += sizeof(struct mod_debug)) {
736+ iter = (struct mod_debug *)value;
737+ register_dynamic_debug_module(iter->modname,
738+ iter->type,
739+ iter->logical_modname,
740+ iter->flag_names, iter->hash, iter->hash2);
741+ }
742+ return 0;
743+}
744+module_init(dynamic_printk_init);
745+/* may want to move this earlier so we can get traces as early as possible */
746+
747+static int __init dynamic_printk_setup(char *str)
748+{
749+ if (str)
750+ return -ENOENT;
751+ set_all(true);
752+ return 0;
753+}
754+/* Use early_param(), so we can get debug output as early as possible */
755+early_param("dynamic_printk", dynamic_printk_setup);
756--- a/lib/Kconfig.debug
757+++ b/lib/Kconfig.debug
758@@ -752,6 +752,61 @@ menuconfig BUILD_DOCSRC
759
760 Say N if you are unsure.
761
762+config DYNAMIC_PRINTK_DEBUG
763+ bool "Enable dynamic printk() call support"
764+ default n
765+ depends on PRINTK
766+ select PRINTK_DEBUG
767+ help
768+
769+ Compiles debug level messages into the kernel, which would not
770+ otherwise be available at runtime. These messages can then be
771+ enabled/disabled on a per module basis. This mechanism implicitly
772+ enables all pr_debug() and dev_dbg() calls. The impact of this
773+ compile option is a larger kernel text size of about 2%.
774+
775+ Usage:
776+
777+ Dynamic debugging is controlled by the debugfs file,
778+ dynamic_printk/modules. This file contains a list of the modules that
779+ can be enabled. The format of the file is the module name, followed
780+ by a set of flags that can be enabled. The first flag is always the
781+ 'enabled' flag. For example:
782+
783+ <module_name> <enabled=0/1>
784+ .
785+ .
786+ .
787+
788+ <module_name> : Name of the module in which the debug call resides
789+ <enabled=0/1> : whether the messages are enabled or not
790+
791+ From a live system:
792+
793+ snd_hda_intel enabled=0
794+ fixup enabled=0
795+ driver enabled=0
796+
797+ Enable a module:
798+
799+ $echo "set enabled=1 <module_name>" > dynamic_printk/modules
800+
801+ Disable a module:
802+
803+ $echo "set enabled=0 <module_name>" > dynamic_printk/modules
804+
805+ Enable all modules:
806+
807+ $echo "set enabled=1 all" > dynamic_printk/modules
808+
809+ Disable all modules:
810+
811+ $echo "set enabled=0 all" > dynamic_printk/modules
812+
813+ Finally, passing "dynamic_printk" at the command line enables
814+ debugging for all modules. This mode can be turned off via the above
815+ disable command.
816+
817 source "samples/Kconfig"
818
819 source "lib/Kconfig.kgdb"
820--- a/lib/Makefile
821+++ b/lib/Makefile
822@@ -81,6 +81,8 @@ obj-$(CONFIG_HAVE_LMB) += lmb.o
823
824 obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
825
826+obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
827+
828 hostprogs-y := gen_crc32table
829 clean-files := crc32table.h
830
831--- a/net/netfilter/nf_conntrack_pptp.c
832+++ b/net/netfilter/nf_conntrack_pptp.c
833@@ -65,7 +65,7 @@ void
834 struct nf_conntrack_expect *exp) __read_mostly;
835 EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
836
837-#ifdef DEBUG
838+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
839 /* PptpControlMessageType names */
840 const char *const pptp_msg_name[] = {
841 "UNKNOWN_MESSAGE",
842--- /dev/null
843+++ b/scripts/basic/hash.c
844@@ -0,0 +1,64 @@
845+/*
846+ * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
847+ *
848+ */
849+
850+#include <stdio.h>
851+#include <stdlib.h>
852+#include <string.h>
853+
854+#define DYNAMIC_DEBUG_HASH_BITS 6
855+
856+static const char *program;
857+
858+static void usage(void)
859+{
860+ printf("Usage: %s <djb2|r5> <modname>\n", program);
861+ exit(1);
862+}
863+
864+/* djb2 hashing algorithm by Dan Bernstein. From:
865+ * http://www.cse.yorku.ca/~oz/hash.html
866+ */
867+
868+unsigned int djb2_hash(char *str)
869+{
870+ unsigned long hash = 5381;
871+ int c;
872+
873+ c = *str;
874+ while (c) {
875+ hash = ((hash << 5) + hash) + c;
876+ c = *++str;
877+ }
878+ return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
879+}
880+
881+unsigned int r5_hash(char *str)
882+{
883+ unsigned long hash = 0;
884+ int c;
885+
886+ c = *str;
887+ while (c) {
888+ hash = (hash + (c << 4) + (c >> 4)) * 11;
889+ c = *++str;
890+ }
891+ return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
892+}
893+
894+int main(int argc, char *argv[])
895+{
896+ program = argv[0];
897+
898+ if (argc != 3)
899+ usage();
900+ if (!strcmp(argv[1], "djb2"))
901+ printf("%d\n", djb2_hash(argv[2]));
902+ else if (!strcmp(argv[1], "r5"))
903+ printf("%d\n", r5_hash(argv[2]));
904+ else
905+ usage();
906+ exit(0);
907+}
908+
909--- a/scripts/basic/Makefile
910+++ b/scripts/basic/Makefile
911@@ -9,7 +9,7 @@
912 # fixdep: Used to generate dependency information during build process
913 # docproc: Used in Documentation/DocBook
914
915-hostprogs-y := fixdep docproc
916+hostprogs-y := fixdep docproc hash
917 always := $(hostprogs-y)
918
919 # fixdep is needed to compile other host programs
920--- a/scripts/Makefile.lib
921+++ b/scripts/Makefile.lib
922@@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUI
923 modname_flags = $(if $(filter 1,$(words $(modname))),\
924 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
925
926+#hash values
927+ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
928+debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
929+ -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
930+else
931+debug_flags =
932+endif
933+
934 orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
935 _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
936 _a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
937@@ -121,7 +129,8 @@ endif
938
939 c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
940 $(__c_flags) $(modkern_cflags) \
941- -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
942+ -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
943+ $(debug_flags)
944
945 a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
946 $(__a_flags) $(modkern_aflags)