Commit 346e15beb5343c2eb8216d820f2ed8f150822b08

Authored by Jason Baron
Committed by Greg Kroah-Hartman
1 parent 33376c1c04

driver core: basic infrastructure for per-module dynamic debug messages

Base infrastructure to enable per-module debug messages.

I've introduced CONFIG_DYNAMIC_PRINTK_DEBUG, which when enabled centralizes
control of debugging statements on a per-module basis in one /proc file,
currently, <debugfs>/dynamic_printk/modules. When, CONFIG_DYNAMIC_PRINTK_DEBUG,
is not set, debugging statements can still be enabled as before, often by
defining 'DEBUG' for the proper compilation unit. Thus, this patch set has no
affect when CONFIG_DYNAMIC_PRINTK_DEBUG is not set.

The infrastructure currently ties into all pr_debug() and dev_dbg() calls. That
is, if CONFIG_DYNAMIC_PRINTK_DEBUG is set, all pr_debug() and dev_dbg() calls
can be dynamically enabled/disabled on a per-module basis.

Future plans include extending this functionality to subsystems, that define
their own debug levels and flags.

Usage:

Dynamic debugging is controlled by the debugfs file,
<debugfs>/dynamic_printk/modules. This file contains a list of the modules that
can be enabled. The format of the file is as follows:

	<module_name> <enabled=0/1>
		.
		.
		.

	<module_name> : Name of the module in which the debug call resides
	<enabled=0/1> : whether the messages are enabled or not

For example:

	snd_hda_intel enabled=0
	fixup enabled=1
	driver enabled=0

Enable a module:

	$echo "set enabled=1 <module_name>" > dynamic_printk/modules

Disable a module:

	$echo "set enabled=0 <module_name>" > dynamic_printk/modules

Enable all modules:

	$echo "set enabled=1 all" > dynamic_printk/modules

Disable all modules:

	$echo "set enabled=0 all" > dynamic_printk/modules

Finally, passing "dynamic_printk" at the command line enables
debugging for all modules. This mode can be turned off via the above
disable command.

[gkh: minor cleanups and tweaks to make the build work quietly]

Signed-off-by: Jason Baron <jbaron@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 14 changed files with 700 additions and 7 deletions Side-by-side Diff

Documentation/kernel-parameters.txt
... ... @@ -1713,6 +1713,11 @@
1713 1713 autoconfiguration.
1714 1714 Ranges are in pairs (memory base and size).
1715 1715  
  1716 + dynamic_printk
  1717 + Enables pr_debug()/dev_dbg() calls if
  1718 + CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also
  1719 + be switched on/off via <debugfs>/dynamic_printk/modules
  1720 +
1716 1721 print-fatal-signals=
1717 1722 [KNL] debug: print fatal signals
1718 1723 print-fatal-signals=1: print segfault info to
include/asm-generic/vmlinux.lds.h
... ... @@ -268,7 +268,15 @@
268 268 CPU_DISCARD(init.data) \
269 269 CPU_DISCARD(init.rodata) \
270 270 MEM_DISCARD(init.data) \
271   - MEM_DISCARD(init.rodata)
  271 + MEM_DISCARD(init.rodata) \
  272 + /* implement dynamic printk debug */ \
  273 + VMLINUX_SYMBOL(__start___verbose_strings) = .; \
  274 + *(__verbose_strings) \
  275 + VMLINUX_SYMBOL(__stop___verbose_strings) = .; \
  276 + . = ALIGN(8); \
  277 + VMLINUX_SYMBOL(__start___verbose) = .; \
  278 + *(__verbose) \
  279 + VMLINUX_SYMBOL(__stop___verbose) = .;
272 280  
273 281 #define INIT_TEXT \
274 282 *(.init.text) \
include/linux/device.h
... ... @@ -550,7 +550,11 @@
550 550 #define dev_info(dev, format, arg...) \
551 551 dev_printk(KERN_INFO , dev , format , ## arg)
552 552  
553   -#ifdef DEBUG
  553 +#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
  554 +#define dev_dbg(dev, format, ...) do { \
  555 + dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
  556 + } while (0)
  557 +#elif defined(DEBUG)
554 558 #define dev_dbg(dev, format, arg...) \
555 559 dev_printk(KERN_DEBUG , dev , format , ## arg)
556 560 #else
include/linux/dynamic_printk.h
  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 +
  13 +extern 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 + */
  19 +extern long long dynamic_printk_enabled;
  20 +extern long long dynamic_printk_enabled2;
  21 +
  22 +struct 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 +
  31 +int 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)
  35 +extern int unregister_dynamic_debug_module(char *mod_name);
  36 +extern 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 +
  78 +static inline int unregister_dynamic_debug_module(const char *mod_name)
  79 +{
  80 + return 0;
  81 +}
  82 +static 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
include/linux/kernel.h
... ... @@ -16,6 +16,7 @@
16 16 #include <linux/log2.h>
17 17 #include <linux/typecheck.h>
18 18 #include <linux/ratelimit.h>
  19 +#include <linux/dynamic_printk.h>
19 20 #include <asm/byteorder.h>
20 21 #include <asm/bug.h>
21 22  
22 23  
... ... @@ -303,8 +304,12 @@
303 304 #define pr_info(fmt, arg...) \
304 305 printk(KERN_INFO fmt, ##arg)
305 306  
306   -#ifdef DEBUG
307 307 /* If you are writing a driver, please use dev_dbg instead */
  308 +#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
  309 +#define pr_debug(fmt, ...) do { \
  310 + dynamic_pr_debug(fmt, ##__VA_ARGS__); \
  311 + } while (0)
  312 +#elif defined(DEBUG)
308 313 #define pr_debug(fmt, arg...) \
309 314 printk(KERN_DEBUG fmt, ##arg)
310 315 #else
include/linux/module.h
... ... @@ -345,7 +345,6 @@
345 345 /* Reference counts */
346 346 struct module_ref ref[NR_CPUS];
347 347 #endif
348   -
349 348 };
350 349 #ifndef MODULE_ARCH_INIT
351 350 #define MODULE_ARCH_INIT {}
... ... @@ -784,6 +784,7 @@
784 784 mutex_lock(&module_mutex);
785 785 /* Store the name of the last unloaded module for diagnostic purposes */
786 786 strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
  787 + unregister_dynamic_debug_module(mod->name);
787 788 free_module(mod);
788 789  
789 790 out:
... ... @@ -1783,6 +1784,33 @@
1783 1784 }
1784 1785 #endif /* CONFIG_KALLSYMS */
1785 1786  
  1787 +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
  1788 +static void dynamic_printk_setup(Elf_Shdr *sechdrs, unsigned int verboseindex)
  1789 +{
  1790 + struct mod_debug *debug_info;
  1791 + unsigned long pos, end;
  1792 + unsigned int num_verbose;
  1793 +
  1794 + pos = sechdrs[verboseindex].sh_addr;
  1795 + num_verbose = sechdrs[verboseindex].sh_size /
  1796 + sizeof(struct mod_debug);
  1797 + end = pos + (num_verbose * sizeof(struct mod_debug));
  1798 +
  1799 + for (; pos < end; pos += sizeof(struct mod_debug)) {
  1800 + debug_info = (struct mod_debug *)pos;
  1801 + register_dynamic_debug_module(debug_info->modname,
  1802 + debug_info->type, debug_info->logical_modname,
  1803 + debug_info->flag_names, debug_info->hash,
  1804 + debug_info->hash2);
  1805 + }
  1806 +}
  1807 +#else
  1808 +static inline void dynamic_printk_setup(Elf_Shdr *sechdrs,
  1809 + unsigned int verboseindex)
  1810 +{
  1811 +}
  1812 +#endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */
  1813 +
1786 1814 static void *module_alloc_update_bounds(unsigned long size)
1787 1815 {
1788 1816 void *ret = module_alloc(size);
... ... @@ -1831,6 +1859,7 @@
1831 1859 #endif
1832 1860 unsigned int markersindex;
1833 1861 unsigned int markersstringsindex;
  1862 + unsigned int verboseindex;
1834 1863 struct module *mod;
1835 1864 long err = 0;
1836 1865 void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
... ... @@ -2117,6 +2146,7 @@
2117 2146 markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
2118 2147 markersstringsindex = find_sec(hdr, sechdrs, secstrings,
2119 2148 "__markers_strings");
  2149 + verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose");
2120 2150  
2121 2151 /* Now do relocations. */
2122 2152 for (i = 1; i < hdr->e_shnum; i++) {
... ... @@ -2167,6 +2197,7 @@
2167 2197 marker_update_probe_range(mod->markers,
2168 2198 mod->markers + mod->num_markers);
2169 2199 #endif
  2200 + dynamic_printk_setup(sechdrs, verboseindex);
2170 2201 err = module_finalize(hdr, sechdrs, mod);
2171 2202 if (err < 0)
2172 2203 goto cleanup;
... ... @@ -807,6 +807,61 @@
807 807  
808 808 Say N if you are unsure.
809 809  
  810 +config DYNAMIC_PRINTK_DEBUG
  811 + bool "Enable dynamic printk() call support"
  812 + default n
  813 + depends on PRINTK
  814 + select PRINTK_DEBUG
  815 + help
  816 +
  817 + Compiles debug level messages into the kernel, which would not
  818 + otherwise be available at runtime. These messages can then be
  819 + enabled/disabled on a per module basis. This mechanism implicitly
  820 + enables all pr_debug() and dev_dbg() calls. The impact of this
  821 + compile option is a larger kernel text size of about 2%.
  822 +
  823 + Usage:
  824 +
  825 + Dynamic debugging is controlled by the debugfs file,
  826 + dynamic_printk/modules. This file contains a list of the modules that
  827 + can be enabled. The format of the file is the module name, followed
  828 + by a set of flags that can be enabled. The first flag is always the
  829 + 'enabled' flag. For example:
  830 +
  831 + <module_name> <enabled=0/1>
  832 + .
  833 + .
  834 + .
  835 +
  836 + <module_name> : Name of the module in which the debug call resides
  837 + <enabled=0/1> : whether the messages are enabled or not
  838 +
  839 + From a live system:
  840 +
  841 + snd_hda_intel enabled=0
  842 + fixup enabled=0
  843 + driver enabled=0
  844 +
  845 + Enable a module:
  846 +
  847 + $echo "set enabled=1 <module_name>" > dynamic_printk/modules
  848 +
  849 + Disable a module:
  850 +
  851 + $echo "set enabled=0 <module_name>" > dynamic_printk/modules
  852 +
  853 + Enable all modules:
  854 +
  855 + $echo "set enabled=1 all" > dynamic_printk/modules
  856 +
  857 + Disable all modules:
  858 +
  859 + $echo "set enabled=0 all" > dynamic_printk/modules
  860 +
  861 + Finally, passing "dynamic_printk" at the command line enables
  862 + debugging for all modules. This mode can be turned off via the above
  863 + disable command.
  864 +
810 865 source "samples/Kconfig"
811 866  
812 867 source "lib/Kconfig.kgdb"
... ... @@ -81,6 +81,8 @@
81 81  
82 82 obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
83 83  
  84 +obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
  85 +
84 86 hostprogs-y := gen_crc32table
85 87 clean-files := crc32table.h
86 88  
lib/dynamic_printk.c
  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 +
  17 +extern struct mod_debug __start___verbose[];
  18 +extern struct mod_debug __stop___verbose[];
  19 +
  20 +struct 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 +
  30 +static int nr_entries;
  31 +static int num_enabled;
  32 +int dynamic_enabled = DYNAMIC_ENABLED_NONE;
  33 +static struct hlist_head module_table[DEBUG_HASH_TABLE_SIZE] =
  34 + { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
  35 +static struct hlist_head module_table2[DEBUG_HASH_TABLE_SIZE] =
  36 + { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
  37 +static 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 + */
  43 +long long dynamic_printk_enabled;
  44 +EXPORT_SYMBOL_GPL(dynamic_printk_enabled);
  45 +long long dynamic_printk_enabled2;
  46 +EXPORT_SYMBOL_GPL(dynamic_printk_enabled2);
  47 +
  48 +/* returns the debug module pointer. */
  49 +static 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. */
  67 +static 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*/
  82 +static 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++;
  113 +out:
  114 + return ret;
  115 +}
  116 +
  117 +int 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--;
  136 +out:
  137 + up(&debug_list_mutex);
  138 + return 0;
  139 +}
  140 +EXPORT_SYMBOL_GPL(unregister_dynamic_debug_module);
  141 +
  142 +int 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;
  161 +out:
  162 + up(&debug_list_mutex);
  163 + return ret;
  164 +}
  165 +EXPORT_SYMBOL_GPL(register_dynamic_debug_module);
  166 +
  167 +int __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 +}
  181 +EXPORT_SYMBOL_GPL(__dynamic_dbg_enabled_helper);
  182 +
  183 +static 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 +
  205 +static 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 +
  224 +static 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 {
  281 + if (elem) {
  282 + if (value && (elem->enable == 0)) {
  283 + dynamic_printk_enabled |=
  284 + (1LL << elem->hash1);
  285 + dynamic_printk_enabled2 |=
  286 + (1LL << elem->hash2);
  287 + elem->enable = 1;
  288 + num_enabled++;
  289 + dynamic_enabled = DYNAMIC_ENABLED_SOME;
  290 + err = 0;
  291 + printk(KERN_DEBUG
  292 + "debugging enabled for module %s",
  293 + elem->name);
  294 + } else if (!value && (elem->enable == 1)) {
  295 + elem->enable = 0;
  296 + num_enabled--;
  297 + if (disabled_hash(elem->hash1, true))
  298 + dynamic_printk_enabled &=
  299 + ~(1LL << elem->hash1);
  300 + if (disabled_hash(elem->hash2, false))
  301 + dynamic_printk_enabled2 &=
  302 + ~(1LL << elem->hash2);
  303 + if (num_enabled)
  304 + dynamic_enabled =
  305 + DYNAMIC_ENABLED_SOME;
  306 + else
  307 + dynamic_enabled =
  308 + DYNAMIC_ENABLED_NONE;
  309 + err = 0;
  310 + printk(KERN_DEBUG
  311 + "debugging disabled for module "
  312 + "%s", elem->name);
  313 + }
  314 + }
  315 + }
  316 + }
  317 + if (!err)
  318 + err = length;
  319 +out_up:
  320 + up(&debug_list_mutex);
  321 +out:
  322 + free_page((unsigned long)buffer);
  323 + return err;
  324 +}
  325 +
  326 +static void *pr_debug_seq_start(struct seq_file *f, loff_t *pos)
  327 +{
  328 + return (*pos < DEBUG_HASH_TABLE_SIZE) ? pos : NULL;
  329 +}
  330 +
  331 +static void *pr_debug_seq_next(struct seq_file *s, void *v, loff_t *pos)
  332 +{
  333 + (*pos)++;
  334 + if (*pos >= DEBUG_HASH_TABLE_SIZE)
  335 + return NULL;
  336 + return pos;
  337 +}
  338 +
  339 +static void pr_debug_seq_stop(struct seq_file *s, void *v)
  340 +{
  341 + /* Nothing to do */
  342 +}
  343 +
  344 +static int pr_debug_seq_show(struct seq_file *s, void *v)
  345 +{
  346 + struct hlist_head *head;
  347 + struct hlist_node *node;
  348 + struct debug_name *elem;
  349 + unsigned int i = *(loff_t *) v;
  350 +
  351 + rcu_read_lock();
  352 + head = &module_table[i];
  353 + hlist_for_each_entry_rcu(elem, node, head, hlist) {
  354 + seq_printf(s, "%s enabled=%d", elem->name, elem->enable);
  355 + seq_printf(s, "\n");
  356 + }
  357 + rcu_read_unlock();
  358 + return 0;
  359 +}
  360 +
  361 +static struct seq_operations pr_debug_seq_ops = {
  362 + .start = pr_debug_seq_start,
  363 + .next = pr_debug_seq_next,
  364 + .stop = pr_debug_seq_stop,
  365 + .show = pr_debug_seq_show
  366 +};
  367 +
  368 +static int pr_debug_open(struct inode *inode, struct file *filp)
  369 +{
  370 + return seq_open(filp, &pr_debug_seq_ops);
  371 +}
  372 +
  373 +static const struct file_operations pr_debug_operations = {
  374 + .open = pr_debug_open,
  375 + .read = seq_read,
  376 + .write = pr_debug_write,
  377 + .llseek = seq_lseek,
  378 + .release = seq_release,
  379 +};
  380 +
  381 +static int __init dynamic_printk_init(void)
  382 +{
  383 + struct dentry *dir, *file;
  384 + struct mod_debug *iter;
  385 + unsigned long value;
  386 +
  387 + dir = debugfs_create_dir("dynamic_printk", NULL);
  388 + if (!dir)
  389 + return -ENOMEM;
  390 + file = debugfs_create_file("modules", 0644, dir, NULL,
  391 + &pr_debug_operations);
  392 + if (!file) {
  393 + debugfs_remove(dir);
  394 + return -ENOMEM;
  395 + }
  396 + for (value = (unsigned long)__start___verbose;
  397 + value < (unsigned long)__stop___verbose;
  398 + value += sizeof(struct mod_debug)) {
  399 + iter = (struct mod_debug *)value;
  400 + register_dynamic_debug_module(iter->modname,
  401 + iter->type,
  402 + iter->logical_modname,
  403 + iter->flag_names, iter->hash, iter->hash2);
  404 + }
  405 + return 0;
  406 +}
  407 +module_init(dynamic_printk_init);
  408 +/* may want to move this earlier so we can get traces as early as possible */
  409 +
  410 +static int __init dynamic_printk_setup(char *str)
  411 +{
  412 + if (str)
  413 + return -ENOENT;
  414 + set_all(true);
  415 + return 0;
  416 +}
  417 +/* Use early_param(), so we can get debug output as early as possible */
  418 +early_param("dynamic_printk", dynamic_printk_setup);
net/netfilter/nf_conntrack_pptp.c
... ... @@ -65,7 +65,7 @@
65 65 struct nf_conntrack_expect *exp) __read_mostly;
66 66 EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
67 67  
68   -#ifdef DEBUG
  68 +#if defined(DEBUG) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
69 69 /* PptpControlMessageType names */
70 70 const char *const pptp_msg_name[] = {
71 71 "UNKNOWN_MESSAGE",
scripts/Makefile.lib
... ... @@ -96,6 +96,14 @@
96 96 modname_flags = $(if $(filter 1,$(words $(modname))),\
97 97 -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
98 98  
  99 +#hash values
  100 +ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
  101 +debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
  102 + -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
  103 +else
  104 +debug_flags =
  105 +endif
  106 +
99 107 orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
100 108 _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
101 109 _a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
... ... @@ -121,7 +129,8 @@
121 129  
122 130 c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
123 131 $(__c_flags) $(modkern_cflags) \
124   - -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
  132 + -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
  133 + $(debug_flags)
125 134  
126 135 a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
127 136 $(__a_flags) $(modkern_aflags)
scripts/basic/Makefile
... ... @@ -9,7 +9,7 @@
9 9 # fixdep: Used to generate dependency information during build process
10 10 # docproc: Used in Documentation/DocBook
11 11  
12   -hostprogs-y := fixdep docproc
  12 +hostprogs-y := fixdep docproc hash
13 13 always := $(hostprogs-y)
14 14  
15 15 # fixdep is needed to compile other host programs
scripts/basic/hash.c
  1 +/*
  2 + * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
  3 + *
  4 + */
  5 +
  6 +#include <stdio.h>
  7 +#include <stdlib.h>
  8 +#include <string.h>
  9 +
  10 +#define DYNAMIC_DEBUG_HASH_BITS 6
  11 +
  12 +static const char *program;
  13 +
  14 +static void usage(void)
  15 +{
  16 + printf("Usage: %s <djb2|r5> <modname>\n", program);
  17 + exit(1);
  18 +}
  19 +
  20 +/* djb2 hashing algorithm by Dan Bernstein. From:
  21 + * http://www.cse.yorku.ca/~oz/hash.html
  22 + */
  23 +
  24 +unsigned int djb2_hash(char *str)
  25 +{
  26 + unsigned long hash = 5381;
  27 + int c;
  28 +
  29 + c = *str;
  30 + while (c) {
  31 + hash = ((hash << 5) + hash) + c;
  32 + c = *++str;
  33 + }
  34 + return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
  35 +}
  36 +
  37 +unsigned int r5_hash(char *str)
  38 +{
  39 + unsigned long hash = 0;
  40 + int c;
  41 +
  42 + c = *str;
  43 + while (c) {
  44 + hash = (hash + (c << 4) + (c >> 4)) * 11;
  45 + c = *++str;
  46 + }
  47 + return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
  48 +}
  49 +
  50 +int main(int argc, char *argv[])
  51 +{
  52 + program = argv[0];
  53 +
  54 + if (argc != 3)
  55 + usage();
  56 + if (!strcmp(argv[1], "djb2"))
  57 + printf("%d\n", djb2_hash(argv[2]));
  58 + else if (!strcmp(argv[1], "r5"))
  59 + printf("%d\n", r5_hash(argv[2]));
  60 + else
  61 + usage();
  62 + exit(0);
  63 +}