diff options
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/device.h | 6 | ||||
-rw-r--r-- | include/linux/dynamic_printk.h | 93 | ||||
-rw-r--r-- | include/linux/kernel.h | 7 | ||||
-rw-r--r-- | include/linux/module.h | 1 |
4 files changed, 104 insertions, 3 deletions
diff --git a/include/linux/device.h b/include/linux/device.h index 60f6456691a..fb034461b39 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -550,7 +550,11 @@ extern const char *dev_driver_string(const struct device *dev); #define dev_info(dev, format, arg...) \ dev_printk(KERN_INFO , dev , format , ## arg) -#ifdef DEBUG +#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG) +#define dev_dbg(dev, format, ...) do { \ + dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \ + } while (0) +#elif defined(DEBUG) #define dev_dbg(dev, format, arg...) \ dev_printk(KERN_DEBUG , dev , format , ## arg) #else diff --git a/include/linux/dynamic_printk.h b/include/linux/dynamic_printk.h new file mode 100644 index 00000000000..2d528d00907 --- /dev/null +++ b/include/linux/dynamic_printk.h @@ -0,0 +1,93 @@ +#ifndef _DYNAMIC_PRINTK_H +#define _DYNAMIC_PRINTK_H + +#define DYNAMIC_DEBUG_HASH_BITS 6 +#define DEBUG_HASH_TABLE_SIZE (1 << DYNAMIC_DEBUG_HASH_BITS) + +#define TYPE_BOOLEAN 1 + +#define DYNAMIC_ENABLED_ALL 0 +#define DYNAMIC_ENABLED_NONE 1 +#define DYNAMIC_ENABLED_SOME 2 + +extern int dynamic_enabled; + +/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which + * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They + * use independent hash functions, to reduce the chance of false positives. + */ +extern long long dynamic_printk_enabled; +extern long long dynamic_printk_enabled2; + +struct mod_debug { + char *modname; + char *logical_modname; + char *flag_names; + int type; + int hash; + int hash2; +} __attribute__((aligned(8))); + +int register_dynamic_debug_module(char *mod_name, int type, char *share_name, + char *flags, int hash, int hash2); + +#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG) +extern int unregister_dynamic_debug_module(char *mod_name); +extern int __dynamic_dbg_enabled_helper(char *modname, int type, + int value, int hash); + +#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ \ + int __ret = 0; \ + if (unlikely((dynamic_printk_enabled & (1LL << DEBUG_HASH)) && \ + (dynamic_printk_enabled2 & (1LL << DEBUG_HASH2)))) \ + __ret = __dynamic_dbg_enabled_helper(module, type, \ + value, hash);\ + __ret; }) + +#define dynamic_pr_debug(fmt, ...) do { \ + static char mod_name[] \ + __attribute__((section("__verbose_strings"))) \ + = KBUILD_MODNAME; \ + static struct mod_debug descriptor \ + __used \ + __attribute__((section("__verbose"), aligned(8))) = \ + { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\ + if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \ + 0, 0, DEBUG_HASH)) \ + printk(KERN_DEBUG KBUILD_MODNAME ":" fmt, \ + ##__VA_ARGS__); \ + } while (0) + +#define dynamic_dev_dbg(dev, format, ...) do { \ + static char mod_name[] \ + __attribute__((section("__verbose_strings"))) \ + = KBUILD_MODNAME; \ + static struct mod_debug descriptor \ + __used \ + __attribute__((section("__verbose"), aligned(8))) = \ + { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\ + if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \ + 0, 0, DEBUG_HASH)) \ + dev_printk(KERN_DEBUG, dev, \ + KBUILD_MODNAME ": " format, \ + ##__VA_ARGS__); \ + } while (0) + +#else + +static inline int unregister_dynamic_debug_module(const char *mod_name) +{ + return 0; +} +static inline int __dynamic_dbg_enabled_helper(char *modname, int type, + int value, int hash) +{ + return 0; +} + +#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ 0; }) +#define dynamic_pr_debug(fmt, ...) do { } while (0) +#define dynamic_dev_dbg(dev, format, ...) do { } while (0) +#endif + +#endif diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 75d81f157d2..ededb6e83b4 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -16,6 +16,7 @@ #include <linux/log2.h> #include <linux/typecheck.h> #include <linux/ratelimit.h> +#include <linux/dynamic_printk.h> #include <asm/byteorder.h> #include <asm/bug.h> @@ -303,8 +304,12 @@ static inline char *pack_hex_byte(char *buf, u8 byte) #define pr_info(fmt, arg...) \ printk(KERN_INFO fmt, ##arg) -#ifdef DEBUG /* If you are writing a driver, please use dev_dbg instead */ +#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG) +#define pr_debug(fmt, ...) do { \ + dynamic_pr_debug(fmt, ##__VA_ARGS__); \ + } while (0) +#elif defined(DEBUG) #define pr_debug(fmt, arg...) \ printk(KERN_DEBUG fmt, ##arg) #else diff --git a/include/linux/module.h b/include/linux/module.h index 68e09557c95..a41555cbe00 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -345,7 +345,6 @@ struct module /* Reference counts */ struct module_ref ref[NR_CPUS]; #endif - }; #ifndef MODULE_ARCH_INIT #define MODULE_ARCH_INIT {} |