dynamic debug v2 - infrastructure
Subsystems (9)
PATCH 1/7 dynamic debug v2 - infrastructure
-infrastructure patch
---
Documentation/kernel-parameters.txt | 5 include/asm-generic/vmlinux.lds.h | 10 - include/linux/device.h | 6 include/linux/dynamic_printk.h | 161 +++++++++ include/linux/kernel.h | 31 ++ include/linux/module.h | 4 kernel/module.c | 23 + lib/Kconfig.debug | 79 +++++ lib/Makefile | 2 lib/dynamic_printk.c | 599 +++++++++++++++++++++++++++++++++++ net/netfilter/nf_conntrack_pptp.c | 2 scripts/Makefile.lib | 11 + scripts/basic/Makefile | 2 scripts/basic/hash.c | 60 ++++ 14 files changed, 986 insertions(+), 9 deletions(-) create mode 100644 include/linux/dynamic_printk.h create mode 100644 lib/dynamic_printk.c create mode 100644 scripts/basic/hash.c
Documentation/kernel-parameters.txt +5 -0
@@ -1580,6 +1580,11 @@ and is between 256 and 4096 characters. It is defined in the file autoconfiguration. Ranges are in pairs (memory base and size). + dynamic_printk + Enables pr_debug()/dev_dbg() calls if + CONFIG_PRINK_DYNAMIC has been enabled. These can also + be switched on/off via <debugfs>/dynamic_printk/modules + print-fatal-signals= [KNL] debug: print fatal signals print-fatal-signals=1: print segfault info to
include/asm-generic/vmlinux.lds.h +8 -2
@@ -167,7 +167,6 @@ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ *(__ksymtab_strings) \ } \ - \/* __*init sections */ \ __init_rodata : AT(ADDR(__init_rodata) - LOAD_OFFSET) { \ *(.ref.rodata) \
@@ -249,7 +248,14 @@ CPU_DISCARD(init.data) \ CPU_DISCARD(init.rodata) \ MEM_DISCARD(init.data) \ - MEM_DISCARD(init.rodata) + MEM_DISCARD(init.rodata) \ + VMLINUX_SYMBOL(__start___verbose_strings) = .; \ + *(__verbose_strings ) \ + VMLINUX_SYMBOL(__stop___verbose_strings) = .; \ + . = ALIGN(8); \ + VMLINUX_SYMBOL(__start___verbose) = .; \ + *(__verbose ) \ + VMLINUX_SYMBOL(__stop___verbose) = .;#define INIT_TEXT \ *(.init.text) \
include/linux/device.h +5 -1
@@ -592,7 +592,11 @@ extern const char *dev_driver_string(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
include/linux/dynamic_printk.h new file +161 -0
161 lines not on this page · raw message
include/linux/kernel.h +28 -3
@@ -14,6 +14,7 @@#include <linux/compiler.h> #include <linux/bitops.h> #include <linux/log2.h> +#include <linux/dynamic_printk.h> #include <asm/byteorder.h> #include <asm/bug.h>
@@ -288,15 +289,39 @@ extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type, #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) + printk(KERN_DEBUG fmt, ##arg)#else #define pr_debug(fmt, arg...) \ ({ if (0) printk(KERN_DEBUG fmt, ##arg); 0; })#endif +#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG ) +#define dynamic_dbg_enabled (call_type, value, level) ({ \ + int ret = _dynamic_dbg_enabled(call_type, value, level);\ + ret; }) +#elif defined(DEBUG ) +#define dynamic_dbg_enabled (type, value, level) do { \ + if (type == TYPE_LEVEL) { \ + if (value < level) \ + return 1; \ + } else if (type == TYPE_FLAG) { \ + if (value & level) \ + return 1; \ + } else if (type == TYPE_BOOLEAN) \ + return 1; \ + return 0; \ + } while (0) +#else +#define dynamic_dbg_enabled (type, value, level) \ + ({ if (0) _dynamic_dbg_enabled(type, value, level); 0; }) +#endif +/* * Display an IP address in readable format. */
include/linux/module.h +4 -0
@@ -359,6 +359,10 @@ struct modulestruct marker *markers;unsigned int num_markers;#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +struct mod_debug *start_verbose; +unsigned int num_verbose; +#endif };#ifndef MODULE_ARCH_INIT #define MODULE_ARCH_INIT {}
kernel/module.c +23 -0
@@ -744,6 +744,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags) }/* Store the name of the last unloaded module for diagnostic purposes */ strlcpy (last_unloaded_module, mod->name,sizeof (last_unloaded_module)); +unregister_debug_module (mod->name);free_module (mod); out:
@@ -1717,6 +1718,9 @@ static struct module *load_module(void __user *umod,unsigned int unusedgplcrcindex;unsigned int markersindex;unsigned int markersstringsindex; +unsigned int verboseindex; +struct mod_debug *iter; +unsigned long value;struct module *mod;long err =0 ;void *percpu =NULL , *ptr =NULL ;/* Stops spurious gcc warning */
@@ -1993,6 +1997,7 @@ static struct module *load_module(void __user *umod, markersindex =find_sec (hdr, sechdrs, secstrings,"__markers" ); markersstringsindex =find_sec (hdr, sechdrs, secstrings,"__markers_strings" ); + verboseindex =find_sec (hdr, sechdrs, secstrings,"__verbose" );/* Now do relocations. */ for (i =1 ; i < hdr->e_shnum; i++) {
@@ -2020,6 +2025,11 @@ static struct module *load_module(void __user *umod, mod->num_markers = sechdrs[markersindex].sh_size /sizeof (*mod->markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG + mod->start_verbose = (void *)sechdrs[verboseindex].sh_addr; + mod->num_verbose = sechdrs[verboseindex].sh_size / +sizeof (*mod->start_verbose); +#endif /* Find duplicate symbols */ err =verify_export_symbols (mod);
@@ -2043,6 +2053,19 @@ static struct module *load_module(void __user *umod,marker_update_probe_range (mod->markers, mod->markers + mod->num_markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +for (value = (unsigned long )mod->start_verbose; + value < (unsigned long )mod->start_verbose + + (unsigned long )(mod->num_verbose *sizeof (struct mod_debug )); + value +=sizeof (struct mod_debug )) { + iter = (struct mod_debug *)value; +register_debug_module (iter->modname, +simple_strtoul (iter->type,NULL ,10 ), + iter->logical_modname, +simple_strtoul (iter->num_flags,NULL ,10 ), + iter->flag_names); + } +#endif err =module_finalize (hdr, sechdrs, mod);if (err <0 ) goto cleanup;
lib/Kconfig.debug +79 -0
85 lines not on this page · raw message
lib/Makefile +2 -0
@@ -70,6 +70,8 @@ lib-$(CONFIG_GENERIC_BUG) += bug.o obj-$(CONFIG_HAVE_LMB) += lmb.o +obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o + hostprogs-y := gen_crc32table clean-files := crc32table.h
lib/dynamic_printk.c new file +599 -0
599 lines not on this page · raw message
net/netfilter/nf_conntrack_pptp.c +1 -1
@@ -65,7 +65,7 @@ void struct nf_conntrack_expect *exp) __read_mostly;EXPORT_SYMBOL_GPL (nf_nat_pptp_hook_expectfn); -#ifdef DEBUG +#if defined(DEBUG ) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG )/* PptpControlMessageType names */ const char *const pptp_msg_name[] = { "UNKNOWN_MESSAGE",
scripts/Makefile.lib +10 -1
@@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") +#hash values +ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +hash_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(modname))" \ + -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(modname))" +else +hash_flags = +endif + _c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o) _a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
@@ -120,7 +128,8 @@ endif c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__c_flags) $(modkern_cflags) \ - -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ + $(hash_flags) a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__a_flags) $(modkern_aflags)
scripts/basic/Makefile +1 -1
@@ -9,7 +9,7 @@ # fixdep: Used to generate dependency information during build process # docproc: Used in Documentation/DocBook -hostprogs-y := fixdep docproc +hostprogs-y := fixdep docproc hash always := $(hostprogs-y) # fixdep is needed to compile other host programs
scripts/basic/hash.c new file +60 -0
60 lines not on this page · raw message
Quoted 7 lines · Jason Baron
include/linux/device.h +0
-0@@ -592,7 +592,11 @@ extern const char *dev_driver_string(struct device *dev); #define dev_info(dev, format, arg...) \ dev_printk(KERN_INFO , dev , format , ## arg)
include/linux/device.h extern const char *dev_driver_string(struct device *dev); · line 602
Quoted 10 lines
include/linux/device.h +5
-1-#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
In looking at your follow-on patches, where you add this to subsystems, it seems that you have to add a lot of #include <linux/dynamic_printk.h> lines.
And in looking at this modification to device.h, I think lots of the kernel should break, but you are getting it "for free" by including the .h file within kernel.h.
Why not also include it here in device.h?
Also, with this change, code that is already using dev_dbg() today is instantly converted over to this logic now, right?
Anyway, this looks great, no objections from me at all, very good work.
thanks,
greg k-h
Quoted 24 lines · Greg KH
Return-Path: <[email protected]>
Quoted 7 lines · Jason Baron
include/linux/device.h +0
-0@@ -592,7 +592,11 @@ extern const char *dev_driver_string(struct device *dev); #define dev_info(dev, format, arg...) \ dev_printk(KERN_INFO , dev , format , ## arg)include/linux/device.h extern const char *dev_driver_string(struct device *dev); · line 602
Quoted 10 lines
include/linux/device.h +5
-1-#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 In looking at your follow-on patches, where you add this to subsystems, it seems that you have to add a lot of #include <
linux/dynamic_printk.h> lines.
Quoted 6 lines
And in looking at this modification to
device.h, I think lots of the kernel should break, but you are getting it "for free" by including the .h file withinkernel.h.Why not also include it here in
device.h?
I don't believe the follow-on patches include "<linux/dynamic_printk.h>". However, some of them do include a subsystem specific #include. For example, the cpufreq subsystem include, <linux/dynamic_debug_cpufreq.h>:
+++ b/include/linux/dynamic_debug_cpufreq.h
@@ -0,0 +1,8 @@
+#define DYNAMIC_DEBUG_NUM_FLAGS "3"
+#define DYNAMIC_DEBUG_FLAG_NAMES "CPUFREQ_DEBUG_CORE,CPUFREQ_DEBUG_DRIVER,CPUFREQ_DEBUG_GOVERNOR" +#define DYNAMIC_DEBUG_TYPE "2"
+#define DYNAMIC_DEBUG_MODNAME "cpufreq_shared"
+
+#ifdef CONFIG_CPU_FREQ_DEBUG
+#define DEBUG 1
+#endif
This header file conveys that cpufreq subsystem, wants non-default options-it has 3 debugging flags that can be set, and all modules in the subsystem are tied together using the module name: "cpufreq_shared".
I don't have an explicit #include of kernel.h in device.h b/c it already picked up.
Quoted 3 lines
Also, with this change, code that is already using
dev_dbg()today is instantly converted over to this logic now, right?
that is correct. any callers of dev_dbg() don't have to do anything. its really only the more complex debugging, where there are flags or levels that need to make adjustments to work with the new infrastructure.
thanks,
-Jason
Quoted 29 lines · Jason Baron
Quoted 28 lines · Greg KH
Return-Path: <[email protected]>
Quoted 7 lines · Jason Baron
include/linux/device.h +0
-0@@ -592,7 +592,11 @@ extern const char *dev_driver_string(struct device *dev); #define dev_info(dev, format, arg...) \ dev_printk(KERN_INFO , dev , format , ## arg)include/linux/device.h extern const char *dev_driver_string(struct device *dev); · line 602
Quoted 10 lines
include/linux/device.h +5
-1-#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 In looking at your follow-on patches, where you add this to subsystems, it seems that you have to add a lot of #include <
linux/dynamic_printk.h> lines.And in looking at this modification to
device.h, I think lots of the kernel should break, but you are getting it "for free" by including the .h file withinkernel.h.
Quoted 6 lines
Quoted 2 lines
Why not also include it here in
device.h?I don't believe the follow-on patches include "<
linux/dynamic_printk.h>". However, some of them do include a subsystem specific #include. For example, the cpufreq subsystem include, <linux/dynamic_debug_cpufreq.h>:
Ah, you are correct, sorry about that, I misread.
Quoted 18 lines
+++
b/include/linux/dynamic_debug_cpufreq.h(quoted diff) +8
-0@@ -0,0 +1,8 @@ +#define DYNAMIC_DEBUG_NUM_FLAGS "3" +#define DYNAMIC_DEBUG_FLAG_NAMES "CPUFREQ_DEBUG_CORE,CPUFREQ_DEBUG_DRIVER,CPUFREQ_DEBUG_GOVERNOR" +#define DYNAMIC_DEBUG_TYPE "2" +#define DYNAMIC_DEBUG_MODNAME "cpufreq_shared" + +#ifdef CONFIG_CPU_FREQ_DEBUG +#define DEBUG 1 +#endifThis header file conveys that cpufreq subsystem, wants non-default options-it has 3 debugging flags that can be set, and all modules in the subsystem are tied together using the module name: "
cpufreq_shared".I don't have an explicit #include of
kernel.hindevice.hb/c it already picked up.
Quoted 7 lines
Quoted 3 lines
Also, with this change, code that is already using
dev_dbg()today is instantly converted over to this logic now, right?that is correct. any callers of
dev_dbg()don't have to do anything. its really only the more complex debugging, where there are flags or levels that need to make adjustments to work with the new infrastructure.
For this reason alone, I see no reason why your patch should not be merged today. You don't need the other subsystems at this point in time in my opinion, it's benifit is huge already.
Not to say that you shouldn't also go after these subsystems in your overall scheme here, but please, don't feel it should hold your code up at this point in time :)
Because of that, do you want me to try to merge the basic infrastructure and dev_dbg() support through the driver-core tree? This code has been in the past -mm and linux-next releases, right?
thanks,
greg k-h
Hi,
Quoted 7 lines · Greg KH
Quoted 3 lines
that is correct. any callers of
dev_dbg()don't have to do anything. its really only the more complex debugging, where there are flags or levels that need to make adjustments to work with the new infrastructure.For this reason alone, I see no reason why your patch should not be merged today. You don't need the other subsystems at this point in time in my opinion, it's benifit is huge already.
not to object to this statement, but:
what about the user-visible interface? currently, it's based around one big debugfs file. What about doing
<debugfs>/dynamic_printk/<module_name>/{enabled[,level][,flag][,modules]}instead, or even
<sysfs>/module/<module_name>/debug/{enabled[,level][,flag]}For "shared" modules like cpufreq (only user so far, AFAICS), things might get a bit more interesting, but we found that out already in the other thread ;)
Best wishes,
Dominik
Quoted 11 lines · Dominik Brodowski
Hi,
Quoted 7 lines · Greg KH
Quoted 3 lines
that is correct. any callers of
dev_dbg()don't have to do anything. its really only the more complex debugging, where there are flags or levels that need to make adjustments to work with the new infrastructure.For this reason alone, I see no reason why your patch should not be merged today. You don't need the other subsystems at this point in time in my opinion, it's benifit is huge already.
Quoted 6 lines
not to object to this statement, but:
what about the user-visible interface? currently, it's based around one big debugfs file. What about doing
<debugfs>/dynamic_printk/<module_name>/{enabled[,level][,flag][,modules]}
By virtue of this being in debugfs, we can change the user interface around as time goes on if we want to with no ill side affects. :)
Quoted 3 lines
instead, or even
<sysfs>/module/<module_name>/debug/{enabled[,level][,flag]}
I like this as that is what a number of current modules do (usb-serial drivers), but you have to be careful about the module parameter namespace to not get collisions here with existing "debug" files.
So for now, I recommend staying in debugfs, it makes more sense.
thanks,
greg k-h
Quoted 5 lines · Greg KH
Quoted 1 line
<sysfs>/module/<module_name>/debug/{enabled[,level][,flag]}I like this as that is what a number of current modules do (usb-serial drivers), but you have to be careful about the module parameter namespace to not get collisions here with existing "debug" files.
That's why I'd put it into a different namespace (debug instead of parameters).
Quoted 1 line
So for now, I recommend staying in debugfs, it makes more sense.
ACK.
Best,
Dominik
Quoted 69 lines · Greg KH
Quoted 29 lines · Jason Baron
Quoted 28 lines · Greg KH
Return-Path: <[email protected]>
Quoted 7 lines · Jason Baron
include/linux/device.h +0
-0@@ -592,7 +592,11 @@ extern const char *dev_driver_string(struct device *dev); #define dev_info(dev, format, arg...) \ dev_printk(KERN_INFO , dev , format , ## arg)include/linux/device.h extern const char *dev_driver_string(struct device *dev); · line 602
Quoted 10 lines
include/linux/device.h +5
-1-#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 In looking at your follow-on patches, where you add this to subsystems, it seems that you have to add a lot of #include <
linux/dynamic_printk.h> lines.And in looking at this modification to
device.h, I think lots of the kernel should break, but you are getting it "for free" by including the .h file withinkernel.h.Quoted 6 lines
Quoted 2 lines
Why not also include it here in
device.h?I don't believe the follow-on patches include "<
linux/dynamic_printk.h>". However, some of them do include a subsystem specific #include. For example, the cpufreq subsystem include, <linux/dynamic_debug_cpufreq.h>:Ah, you are correct, sorry about that, I misread.
Quoted 18 lines
+++
b/include/linux/dynamic_debug_cpufreq.h(quoted diff) +8
-0@@ -0,0 +1,8 @@ +#define DYNAMIC_DEBUG_NUM_FLAGS "3" +#define DYNAMIC_DEBUG_FLAG_NAMES "CPUFREQ_DEBUG_CORE,CPUFREQ_DEBUG_DRIVER,CPUFREQ_DEBUG_GOVERNOR" +#define DYNAMIC_DEBUG_TYPE "2" +#define DYNAMIC_DEBUG_MODNAME "cpufreq_shared" + +#ifdef CONFIG_CPU_FREQ_DEBUG +#define DEBUG 1 +#endifThis header file conveys that cpufreq subsystem, wants non-default options-it has 3 debugging flags that can be set, and all modules in the subsystem are tied together using the module name: "
cpufreq_shared".I don't have an explicit #include of
kernel.hindevice.hb/c it already picked up.Quoted 7 lines
Quoted 3 lines
Also, with this change, code that is already using
dev_dbg()today is instantly converted over to this logic now, right?that is correct. any callers of
dev_dbg()don't have to do anything. its really only the more complex debugging, where there are flags or levels that need to make adjustments to work with the new infrastructure.For this reason alone, I see no reason why your patch should not be merged today. You don't need the other subsystems at this point in time in my opinion, it's benifit is huge already.
Quoted 8 lines
Not to say that you shouldn't also go after these subsystems in your overall scheme here, but please, don't feel it should hold your code up at this point in time :)
Because of that, do you want me to try to merge the basic infrastructure and
dev_dbg()support through the driver-core tree? This code has been in the past -mm and linux-next releases, right?
On my system, with just the pr_debug, dev_dbg() hooks, i get about 80 modules loaded that i can enable/disable debugging for. So, this piece is useful by itself as you point out.
However, there are a couple important issues that need to be resolved. One is the the infrastructure relies on 'KBUILD_MODNAME' to differentiate modules. However, these are not necessarily unique within the tree. For example, mm/mmap.c and arch/x86/mm/mmap.c both have the 'KBUILD_MODNAME' of 'mmap'. Thus, enabling debugging for one of these will enabled both. Perhaps, this is the desired affect, but there might be cases where we want to differentiate? We could use a combination of directory location in combination with 'KBUILD_MODNAME'.
The second issue, is the splitting up the control file from one monolithic one, to one per module...i did one monolithic one to make the implementation simpler but we could definitely split it up.
So, yes it could go in now, or I can try and polish it a little more...it has not yet had a runtime in either -mm or linux-next yet.
thanks,
-Jason
Quoted 13 lines · Greg KH
Quoted 8 lines
Quoted 4 lines
Also, with this change, code that is already using
dev_dbg()today is instantly converted over to this logic now, right?that is correct. any callers of
dev_dbg()don't have to do anything. its really only the more complex debugging, where there are flags or levels that need to make adjustments to work with the new infrastructure.For this reason alone, I see no reason why your patch should not be merged today. You don't need the other subsystems at this point in time in my opinion, it's benifit is huge already.
Quoted 8 lines
Not to say that you shouldn't also go after these subsystems in your overall scheme here, but please, don't feel it should hold your code up at this point in time :)
Because of that, do you want me to try to merge the basic infrastructure and
dev_dbg()support through the driver-core tree? This code has been in the past -mm and linux-next releases, right?
ok, here's a patch that implements just the basic core functionality that ties into pr_debug() and dev_dbg(). That is, any users of those two functions can be dynamically enabled/disabled at runtime if CONFIG_DYNAMIC_PRINTK_DEBUG is set at compile time. We can add the more complex flag/level debugging later as you suggest...
Few notes...there is still one control file: <debugfs>/dynamic_printk/modules We can split this up now or later, but I kind of like being able to see all the controls in one file. Also, i've used a djb2 hash function in the code, which i'm not sure is under the correct license/copyright, so i just wanted to point that out as well. see: scripts/basic/hash.c. If its an issue, i can find another hash function.
thanks,
-Jason
---
Documentation/kernel-parameters.txt | 5 include/asm-generic/vmlinux.lds.h | 10 + include/linux/device.h | 6 - include/linux/dynamic_printk.h | 94 ++++++++ include/linux/kernel.h | 7 + include/linux/module.h | 4 kernel/module.c | 22 ++ lib/Kconfig.debug | 56 +++++ lib/Makefile | 2 lib/dynamic_printk.c | 409 +++++++++++++++++++++++++++++++++++ net/netfilter/nf_conntrack_pptp.c | 2 scripts/Makefile.lib | 11 + scripts/basic/Makefile | 2 scripts/basic/hash.c | 64 +++++ 14 files changed, 688 insertions(+), 6 deletions(-) create mode 100644 include/linux/dynamic_printk.h create mode 100644 lib/dynamic_printk.c create mode 100644 scripts/basic/hash.c
Documentation/kernel-parameters.txt +5 -0
@@ -1580,6 +1580,11 @@ and is between 256 and 4096 characters. It is defined in the file autoconfiguration. Ranges are in pairs (memory base and size). + dynamic_printk + Enables pr_debug()/dev_dbg() calls if + CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also + be switched on/off via <debugfs>/dynamic_printk/modules + print-fatal-signals= [KNL] debug: print fatal signals print-fatal-signals=1: print segfault info to
include/asm-generic/vmlinux.lds.h +9 -1
@@ -249,7 +249,15 @@ CPU_DISCARD(init.data) \ CPU_DISCARD(init.rodata) \ MEM_DISCARD(init.data) \ - MEM_DISCARD(init.rodata) +MEM_DISCARD (init.rodata) \ + /* implement dynamic printk debug */ \ + VMLINUX_SYMBOL(__start___verbose_strings) = .; \ + *(__verbose_strings ) \ + VMLINUX_SYMBOL(__stop___verbose_strings) = .; \ + . = ALIGN(8); \ + VMLINUX_SYMBOL(__start___verbose) = .; \ + *(__verbose ) \ + VMLINUX_SYMBOL(__stop___verbose) = .;#define INIT_TEXT \ *(.init.text) \
include/linux/device.h +5 -1
@@ -592,7 +592,11 @@ extern const char *dev_driver_string(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
include/linux/dynamic_printk.h new file +94 -0
94 lines not on this page · raw message
include/linux/kernel.h +6 -1
@@ -14,6 +14,7 @@#include <linux/compiler.h> #include <linux/bitops.h> #include <linux/log2.h> +#include <linux/dynamic_printk.h> #include <asm/byteorder.h> #include <asm/bug.h>
@@ -288,8 +289,12 @@ extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type, #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
include/linux/module.h +4 -0
@@ -359,6 +359,10 @@ struct modulestruct marker *markers;unsigned int num_markers;#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +struct mod_debug *start_verbose; +unsigned int num_verbose; +#endif };#ifndef MODULE_ARCH_INIT #define MODULE_ARCH_INIT {}
kernel/module.c +22 -0
@@ -744,6 +744,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags) }/* Store the name of the last unloaded module for diagnostic purposes */ strlcpy (last_unloaded_module, mod->name,sizeof (last_unloaded_module)); +unregister_dynamic_debug_module (mod->name);free_module (mod); out:
@@ -1717,6 +1718,9 @@ static struct module *load_module(void __user *umod,unsigned int unusedgplcrcindex;unsigned int markersindex;unsigned int markersstringsindex; +unsigned int verboseindex; +struct mod_debug *iter; +unsigned long value;struct module *mod;long err =0 ;void *percpu =NULL , *ptr =NULL ;/* Stops spurious gcc warning */
@@ -1993,6 +1997,7 @@ static struct module *load_module(void __user *umod, markersindex =find_sec (hdr, sechdrs, secstrings,"__markers" ); markersstringsindex =find_sec (hdr, sechdrs, secstrings,"__markers_strings" ); + verboseindex =find_sec (hdr, sechdrs, secstrings,"__verbose" );/* Now do relocations. */ for (i =1 ; i < hdr->e_shnum; i++) {
@@ -2020,6 +2025,11 @@ static struct module *load_module(void __user *umod, mod->num_markers = sechdrs[markersindex].sh_size /sizeof (*mod->markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG + mod->start_verbose = (void *)sechdrs[verboseindex].sh_addr; + mod->num_verbose = sechdrs[verboseindex].sh_size / +sizeof (*mod->start_verbose); +#endif /* Find duplicate symbols */ err =verify_export_symbols (mod);
@@ -2043,6 +2053,18 @@ static struct module *load_module(void __user *umod,marker_update_probe_range (mod->markers, mod->markers + mod->num_markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +for (value = (unsigned long )mod->start_verbose; + value < (unsigned long )mod->start_verbose + + (unsigned long )(mod->num_verbose *sizeof (struct mod_debug )); + value +=sizeof (struct mod_debug )) { + iter = (struct mod_debug *)value; +register_dynamic_debug_module (iter->modname, + iter->type, + iter->logical_modname, + iter->flag_names, iter->hash, iter->hash2); + } +#endif err =module_finalize (hdr, sechdrs, mod);if (err <0 ) goto cleanup;
lib/Kconfig.debug +56 -0
62 lines not on this page · raw message
lib/Makefile +2 -0
@@ -70,6 +70,8 @@ lib-$(CONFIG_GENERIC_BUG) += bug.o obj-$(CONFIG_HAVE_LMB) += lmb.o +obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o + hostprogs-y := gen_crc32table clean-files := crc32table.h
lib/dynamic_printk.c new file +409 -0
409 lines not on this page · raw message
net/netfilter/nf_conntrack_pptp.c +1 -1
@@ -65,7 +65,7 @@ void struct nf_conntrack_expect *exp) __read_mostly;EXPORT_SYMBOL_GPL (nf_nat_pptp_hook_expectfn); -#ifdef DEBUG +#if defined(DEBUG ) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG )/* PptpControlMessageType names */ const char *const pptp_msg_name[] = { "UNKNOWN_MESSAGE",
scripts/Makefile.lib +10 -1
@@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") +#hash values +ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\ + -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))" +else +debug_flags = +endif + _c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o) _a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
@@ -120,7 +128,8 @@ endif c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__c_flags) $(modkern_cflags) \ - -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ + $(debug_flags) a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__a_flags) $(modkern_aflags)
scripts/basic/Makefile +1 -1
@@ -9,7 +9,7 @@ # fixdep: Used to generate dependency information during build process # docproc: Used in Documentation/DocBook -hostprogs-y := fixdep docproc +hostprogs-y := fixdep docproc hash always := $(hostprogs-y) # fixdep is needed to compile other host programs
scripts/basic/hash.c new file +64 -0
64 lines not on this page · raw message
Quoted 6 lines · Jason Baron
ok, here's a patch that implements just the basic core functionality that ties into
pr_debug()anddev_dbg(). That is, any users of those two functions can be dynamically enabled/disabled at runtime ifCONFIG_DYNAMIC_PRINTK_DEBUGis set at compile time. We can add the more complex flag/level debugging later as you suggest...
Very nice, just as I'm writing patches to dynamically make CONFIG_USB_DEBUG be selectable on the fly :)
Don't worry, that can easily be moved over to your version once it is done and in the tree...
Quoted 6 lines
Few notes...there is still one control file: <debugfs>/dynamic_printk/modules We can split this up now or later, but I kind of like being able to see all the controls in one file. Also, i've used a djb2 hash function in the code, which i'm not sure is under the correct license/copyright, so i just wanted to point that out as well. see:
scripts/basic/hash.c. If its an issue, i can find another hash function.
Why use that hash function? Actually, it looks like you are using 2 different ones, right? Why?
include/linux/dynamic_printk.h line 4
Quoted 7 lines
include/linux/dynamic_printk.h new file +4
-0@@ -0,0 +1,94 @@ +#ifndef _DYNAMIC_PRINTK_H +#define _DYNAMIC_PRINTK_H + +#ifdef __KERNEL__
Shouldn't be needed.
include/linux/dynamic_printk.h line 12
Quoted 7 lines
include/linux/dynamic_printk.h new file +7
-0+#include <linux/string.h> +#include <linux/hash.h> + +#define DYNAMIC_DEBUG_HASH_BITS 6 +#define DEBUG_HASH_TABLE_SIZE (1 << DYNAMIC_DEBUG_HASH_BITS) + +#define TYPE_BOOLEAN 1
What's this for?
include/linux/dynamic_printk.h line 20
Quoted 7 lines
include/linux/dynamic_printk.h new file +7
-0+#define DYNAMIC_ENABLED_ALL 0 +#define DYNAMIC_ENABLED_NONE 1 +#define DYNAMIC_ENABLED_SOME 2 + +extern int dynamic_enabled; +extern long long dynamic_printk_enabled; +extern long long dynamic_printk_enabled2;
What's up with the "2" versions?
include/linux/dynamic_printk.h line 30
Quoted 12 lines
include/linux/dynamic_printk.h new file +12
-0+config DYNAMIC_PRINTK_DEBUG + bool "Enable dynamic printk() call support" + default n + depends onPRINTK + selectPRINTK_DEBUG + help + + Compiles debug level messages into the kernel, which would not + otherwise be available at runtime. These messages can then be + enabled/disabled on a per module basis. This mechanism, implicitly + enables all pr_debug() and dev_dbg() calls. The impact of this + compile option is a larger kernel text size ~2%.
Trailing spaces :(
It's looking very good so far.
thanks,
greg k-h
Quoted 10 lines · Greg KH
Quoted 6 lines
Few notes...there is still one control file: <debugfs>/dynamic_printk/modules We can split this up now or later, but I kind of like being able to see all the controls in one file. Also, i've used a djb2 hash function in the code, which i'm not sure is under the correct license/copyright, so i just wanted to point that out as well. see:
scripts/basic/hash.c. If its an issue, i can find another hash function.Why use that hash function? Actually, it looks like you are using 2 different ones, right? Why?
The hash functions are used to map between the calling module name, KBUILD_MODNAME, and whether or not debugging is enabled. In the 'fast' case a bitmask is used to represent each hash bucket. One bit per bucket. Thus, if all the modules in a bucket are disabled the bitmask is simply 0. Two hashes are used in order to reduce the probability of collisions, used in this way it is similar to a bloom filter. The code that implements this is:
#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; })where DEBUG_HASH and DEBUG_HASH2 are computed at compile time. Thus, in the 'fast' case where debugging is off, we have two extra intructions, a test and a jmp. Further, if we enable debugging for a single module, we will at most do two 'tests' and a jump for disabled modules. If the module is enabled, we would call through to __dynamic_dbg_enabled_helper(), which verifies whether or not debugging is enabled for the module. I believe if we are then calling 'printk()' the cost of this function call is 'in the noise'. Thus, i've tried to optimize the disabled case.
Quoted 10 lines
include/linux/dynamic_printk.h line 4
Quoted 7 lines
include/linux/dynamic_printk.h new file +4
-0@@ -0,0 +1,94 @@ +#ifndef _DYNAMIC_PRINTK_H +#define _DYNAMIC_PRINTK_H + +#ifdef __KERNEL__Shouldn't be needed.
ok
Quoted 10 lines
include/linux/dynamic_printk.h line 12
Quoted 7 lines
include/linux/dynamic_printk.h new file +7
-0+#include <linux/string.h> +#include <linux/hash.h> + +#define DYNAMIC_DEBUG_HASH_BITS 6 +#define DEBUG_HASH_TABLE_SIZE (1 << DYNAMIC_DEBUG_HASH_BITS) + +#define TYPE_BOOLEAN 1What's this for?
This is really in anticipation of more 'involved' dynamic debugging. That is, 'TYPE_BOOLEAN', just means the debugging is either off/on. The other types are 'TYPE_FLAG', where you can control debugging for a module via a bitmask, or 'TYPE_LEVEL', where you control the debugging for a module via a level control like printk levels. These different types were implemented in the orginal patchset.
Quoted 10 lines
include/linux/dynamic_printk.h line 20
Quoted 7 lines
include/linux/dynamic_printk.h new file +7
-0+#define DYNAMIC_ENABLED_ALL 0 +#define DYNAMIC_ENABLED_NONE 1 +#define DYNAMIC_ENABLED_SOME 2 + +extern int dynamic_enabled; +extern long long dynamic_printk_enabled; +extern long long dynamic_printk_enabled2;What's up with the "2" versions?
"2" here is the second bitmask as explained previously.
thanks,
-Jason
Quoted 4 lines · Jason Baron
Quoted 2 lines
What's up with the "2" versions?
"2" here is the second bitmask as explained previously.
Great, thanks for doing this, can you put this description in the code so it doesn't come up again? :)
thanks,
greg k-h
Quoted 6 lines · On Fri, 8 Aug 2008 17:51:53 -0400 Jason Baron wrote:
Few notes...there is still one control file: <debugfs>/dynamic_printk/modules We can split this up now or later, but I kind of like being able to see all the controls in one file. Also, i've used a djb2 hash function in the code, which i'm not sure is under the correct license/copyright, so i just wanted to point that out as well. see:
scripts/basic/hash.c. If its an issue, i can find another hash function.
What license does it have? I don't see one.
Quoted 31 lines
---
Documentation/kernel-parameters.txt | 5 include/asm-generic/vmlinux.lds.h | 10 + include/linux/device.h | 6 - include/linux/dynamic_printk.h | 94 ++++++++ include/linux/kernel.h | 7 + include/linux/module.h | 4 kernel/module.c | 22 ++ lib/Kconfig.debug | 56 +++++ lib/Makefile | 2 lib/dynamic_printk.c | 409 +++++++++++++++++++++++++++++++++++ net/netfilter/nf_conntrack_pptp.c | 2 scripts/Makefile.lib | 11 + scripts/basic/Makefile | 2 scripts/basic/hash.c | 64 +++++ 14 files changed, 688 insertions(+), 6 deletions(-) create mode 100644 include/linux/dynamic_printk.h create mode 100644 lib/dynamic_printk.c create mode 100644 scripts/basic/hash.clib/Kconfig.debug +0
-0@@ -632,6 +632,62 @@ config FIREWIRE_OHCI_REMOTE_DMA If unsure, say N.
lib/Kconfig.debug config FIREWIRE_OHCI_REMOTE_DMA · line 644
Quoted 10 lines
lib/Kconfig.debug +10
-0+config DYNAMIC_PRINTK_DEBUG + bool "Enable dynamic printk() call support" + default n + depends on PRINTK + select PRINTK_DEBUG + help + + Compiles debug level messages into the kernel, which would not + otherwise be available at runtime. These messages can then be + enabled/disabled on a per module basis. This mechanism, implicitly
no comma. Don't end lines with whitespace.
lib/Kconfig.debug config FIREWIRE_OHCI_REMOTE_DMA · line 646
Quoted 2 lines
lib/Kconfig.debug +2
-0+ enables all pr_debug() and dev_dbg() calls. The impact of this + compile option is a larger kernel text size ~2%.
size of about 2%.
lib/Kconfig.debug config FIREWIRE_OHCI_REMOTE_DMA · line 653
Quoted 7 lines
lib/Kconfig.debug +7
-0+ + Usage: + + Dynamic debugging is controlled by the debugfs file, + dynamic_printk/modules. This file contains a list of the modules that + can be enabled. The format of the file is the module name, followed + by a set of flags that can be enabled. The first flags is always the
first flag is
lib/Kconfig.debug config FIREWIRE_OHCI_REMOTE_DMA · line 654
Quoted 1 line
lib/Kconfig.debug +1
-0+ 'enabled' flags. For example:
flag.
lib/Kconfig.debug config FIREWIRE_OHCI_REMOTE_DMA · line 662
Quoted 8 lines
lib/Kconfig.debug +8
-0+ + <module_name> <enabled=0/1> + . + . + . + + <module_name> : Name of the module in which the debug call resides + <enabled=0/1> : whether the the messages are enabled or not
the
lib/Kconfig.debug config FIREWIRE_OHCI_REMOTE_DMA · line 670
Quoted 8 lines
lib/Kconfig.debug +8
-0+ + From a live system: + + snd_hda_intel enabled=0 + + fixup enabled=0 + + driver enabled=0
including the apparently extraneous blank lines??
Quoted 9 lines
lib/Kconfig.debug +9
-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 +
lib/Kconfig.debug config FIREWIRE_OHCI_REMOTE_DMA · line 689
Quoted 10 lines
lib/Kconfig.debug +10
-0+ 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 all + modules. This mode can be turned off by disabling modules.
What does "can be turned off by disabling modules" mean, please? CONFIG_MODULES=n or something else?
lib/dynamic_printk.c line 3
Quoted 13 lines
lib/Kconfig.debug +1
-0+ source "samples/Kconfig" source "lib/Kconfig.kgdb"lib/dynamic_printk.c new file +3
-0@@ -0,0 +1,409 @@ + +extern struct mod_debug __start___verbose[]; +extern struct mod_debug __stop___verbose[];
put these into a header file.
Quoted 16 lines
lib/dynamic_printk.c new file +16
-0+ +struct debug_name { +struct hlist_node hlist; +struct hlist_node hlist2; +int hash1; +int hash2; +char *name; +int enable; +int type; +}; + +static int nr_entries; +static int num_enabled; +int dynamic_enabled =DYNAMIC_ENABLED_NONE ; +static struct hlist_head module_table[DEBUG_HASH_TABLE_SIZE ] = + { [0 ...DEBUG_HASH_TABLE_SIZE -1 ] =HLIST_HEAD_INIT };
lib/dynamic_printk.c line 44
Quoted 10 lines
lib/dynamic_printk.c new file +10
-0+static struct hlist_head module_table2[DEBUG_HASH_TABLE_SIZE ] = + { [0 ...DEBUG_HASH_TABLE_SIZE -1 ] =HLIST_HEAD_INIT }; +static DECLARE_MUTEX (debug_list_mutex); + +long long dynamic_printk_enabled; +EXPORT_SYMBOL_GPL (dynamic_printk_enabled); +long long dynamic_printk_enabled2; +EXPORT_SYMBOL_GPL (dynamic_printk_enabled2); + +/* returns the debug module pointer. caller must locking */
caller must ___ locking ??
Quoted 8 lines
lib/dynamic_printk.c new file +8
-0+static struct debug_name *find_debug_module (char *module_name) +{ +int i; +struct hlist_head *head; +struct hlist_node *node; +struct debug_name *element; + + element =NULL ;
lib/dynamic_printk.c line 62
Quoted 10 lines
lib/dynamic_printk.c new file +10
-0+for (i =0 ; i <DEBUG_HASH_TABLE_SIZE ; i++) { + head = &module_table[i]; +hlist_for_each_entry_rcu (element, node, head, hlist) +if (!strcmp (element->name, module_name)) +return element; + } +return NULL ; +} + +/* returns the debug module pointer. caller must locking */
ditto, check comment.
Quoted 4 lines
lib/dynamic_printk.c new file +4
-0+static struct debug_name *find_debug_module_hash (char *module_name,int hash) +{ +struct hlist_head *head; +struct hlist_node *node;
lib/dynamic_printk.c line 76
Quoted 10 lines
lib/dynamic_printk.c new file +10
-0+struct debug_name *element; + + element =NULL ; + head = &module_table[hash]; +hlist_for_each_entry_rcu (element, node, head, hlist) +if (!strcmp (element->name, module_name)) +return element; +return NULL ; +} +
Please add kernel-doc comments for the exported/public interfaces.
Quoted 111 lines
lib/dynamic_printk.c new file +51
-0+int unregister_dynamic_debug_module (char *mod_name) +{ +struct debug_name *element; +int ret =0 ; + +down (&debug_list_mutex); + element =find_debug_module (mod_name); +if (!element) { + ret = -EINVAL ; + goto out; + } +hlist_del_rcu (&element->hlist); +hlist_del_rcu (&element->hlist2); +synchronize_rcu (); +if (element->name) +kfree (element->name); +if (element->enable) + num_enabled--; +kfree (element); + nr_entries--; +out: +up (&debug_list_mutex); +return 0 ; +} +EXPORT_SYMBOL_GPL (unregister_dynamic_debug_module); + +int register_dynamic_debug_module (char *mod_name,int type,char *share_name, +char *flags,int hash,int hash2) +{ +struct debug_name *elem; +int ret =0 ; + +down (&debug_list_mutex); + elem =find_debug_module (mod_name); +if (!elem) { +if (__add_debug_module (mod_name, hash, hash2)) + goto out; + elem =find_debug_module (mod_name); +if (dynamic_enabled ==DYNAMIC_ENABLED_ALL && + !strcmp (mod_name, share_name)) { + elem->enable = true; + num_enabled++; + } + } + elem->type |= type; +out: +up (&debug_list_mutex); +return ret; +} +EXPORT_SYMBOL_GPL (register_dynamic_debug_module); +scripts/basic/hash.c new file +53
-0@@ -0,0 +1,64 @@ +/* +* Copyright (C) 2008 Red Hat, Inc., Jason Baron <[email protected]> +* +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define DYNAMIC_DEBUG_HASH_BITS 6 + +static const char *program; + +static void usage (void ) +{ +printf ("Usage: %s <djb2|r5> <modname>\n" , program); +exit (1 ); +} + +/* djb2 hashing algorithm by Dan Bernstein. From: +* http://www.cse.yorku.ca/~oz/hash.html +*/ + +unsigned int djb2_hash (char *str) +{ +unsigned long hash =5381 ; +int c; + + c = *str; +while (c) { + hash = ((hash <<5 ) + hash) + c; + c = *++str; + } +return (unsigned int )(hash & ((1 <<DYNAMIC_DEBUG_HASH_BITS ) -1 )); +} + +unsigned int r5_hash (char *str) +{ +unsigned long hash =0 ; +int c; + + c = *str; +while (c) { + hash = (hash + (c <<4 ) + (c >>4 )) *11 ; + c = *++str; + } +return (unsigned int )(hash & ((1 <<DYNAMIC_DEBUG_HASH_BITS ) -1 )); +} + +int main (int argc,char *argv[]) +{ + program = argv[0 ]; +
scripts/basic/hash.c line 63
Quoted 10 lines
scripts/basic/hash.c new file +10
-0+if (argc !=3 ) +usage (); +if (!strcmp (argv[1 ],"djb2" )) +printf ("%d\n" ,djb2_hash (argv[2 ])); +else if (!strcmp (argv[1 ],"r5" )) +printf ("%d\n" ,r5_hash (argv[2 ])); +else +usage (); +exit (0 ); +}
---
~Randy
Linux Plumbers Conference, 17-19 September 2008, Portland, Oregon USA
http://linuxplumbersconf.org/
Quoted 11 lines · Randy Dunlap
Quoted 6 lines · On Fri, 8 Aug 2008 17:51:53 -0400 Jason Baron wrote:
Few notes...there is still one control file: <debugfs>/dynamic_printk/modules We can split this up now or later, but I kind of like being able to see all the controls in one file. Also, i've used a djb2 hash function in the code, which i'm not sure is under the correct license/copyright, so i just wanted to point that out as well. see:
scripts/basic/hash.c. If its an issue, i can find another hash function.What license does it have? I don't see one.
hmmm...a search for djb2 finds a number of users, for example, i found this one which is covered by GPL2, http://www.telegraphics.com.au/svn/dpa/trunk/symtab.c
is that sufficient to say its ok?
i'll clean up the additional points that you raised.
thanks,
-Jason
Quoted 10 lines · Jason Baron
Quoted 9 lines · Randy Dunlap
Quoted 6 lines · On Fri, 8 Aug 2008 17:51:53 -0400 Jason Baron wrote:
Few notes...there is still one control file: <debugfs>/dynamic_printk/modules We can split this up now or later, but I kind of like being able to see all the controls in one file. Also, i've used a djb2 hash function in the code, which i'm not sure is under the correct license/copyright, so i just wanted to point that out as well. see:
scripts/basic/hash.c. If its an issue, i can find another hash function.
Quoted 6 lines
Quoted 2 lines
What license does it have? I don't see one.
hmmm...a search for djb2 finds a number of users, for example, i found this one which is covered by GPL2, http://www.telegraphics.com.au/svn/dpa/trunk/symtab.c
is that sufficient to say its ok?
That's a tough call. I'd run that through the license board of your employer if you have any questions about this, as it is your name with their domain that is going to have the "signed-off-by:" pointing back to.
thanks,
greg k-h
Quoted 14 lines · Greg KH
Quoted 13 lines · Jason Baron
Quoted 11 lines · Randy Dunlap
Quoted 6 lines · On Fri, 8 Aug 2008 17:51:53 -0400 Jason Baron wrote:
Few notes...there is still one control file: <debugfs>/dynamic_printk/modules We can split this up now or later, but I kind of like being able to see all the controls in one file. Also, i've used a djb2 hash function in the code, which i'm not sure is under the correct license/copyright, so i just wanted to point that out as well. see:
scripts/basic/hash.c. If its an issue, i can find another hash function.What license does it have? I don't see one.
Quoted 9 lines
Quoted 3 lines
hmmm...a search for djb2 finds a number of users, for example, i found this one which is covered by GPL2, http://www.telegraphics.com.au/svn/dpa/trunk/symtab.c
is that sufficient to say its ok?That's a tough call. I'd run that through the license board of your employer if you have any questions about this, as it is your name with their domain that is going to have the "signed-off-by:" pointing back to.
We're ok with the patch as is...i'm including an updated version below, which contains some documentation improvements...as you mentioned before, perhaps you can include this patch through the driver tree. It should apply with minimal munging, but please point me at a tree, if there are any issues.
thanks,
-Jason
---
Documentation/kernel-parameters.txt | 5 include/asm-generic/vmlinux.lds.h | 10 + include/linux/device.h | 6 - include/linux/dynamic_printk.h | 96 ++++++++ include/linux/kernel.h | 7 + include/linux/module.h | 4 kernel/module.c | 22 ++ lib/Kconfig.debug | 55 +++++ lib/Makefile | 2 lib/dynamic_printk.c | 413 +++++++++++++++++++++++++++++++++++ net/netfilter/nf_conntrack_pptp.c | 2 scripts/Makefile.lib | 11 + scripts/basic/Makefile | 2 scripts/basic/hash.c | 64 +++++ 14 files changed, 693 insertions(+), 6 deletions(-) create mode 100644 include/linux/dynamic_printk.h create mode 100644 lib/dynamic_printk.c create mode 100644 scripts/basic/hash.c
Documentation/kernel-parameters.txt +5 -0
@@ -1580,6 +1580,11 @@ and is between 256 and 4096 characters. It is defined in the file autoconfiguration. Ranges are in pairs (memory base and size). + dynamic_printk + Enables pr_debug()/dev_dbg() calls if + CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also + be switched on/off via <debugfs>/dynamic_printk/modules + print-fatal-signals= [KNL] debug: print fatal signals print-fatal-signals=1: print segfault info to
include/asm-generic/vmlinux.lds.h +9 -1
@@ -249,7 +249,15 @@ CPU_DISCARD(init.data) \ CPU_DISCARD(init.rodata) \ MEM_DISCARD(init.data) \ - MEM_DISCARD(init.rodata) +MEM_DISCARD (init.rodata) \ + /* implement dynamic printk debug */ \ + VMLINUX_SYMBOL(__start___verbose_strings) = .; \ + *(__verbose_strings ) \ + VMLINUX_SYMBOL(__stop___verbose_strings) = .; \ + . = ALIGN(8); \ + VMLINUX_SYMBOL(__start___verbose) = .; \ + *(__verbose ) \ + VMLINUX_SYMBOL(__stop___verbose) = .;#define INIT_TEXT \ *(.init.text) \
include/linux/device.h +5 -1
@@ -592,7 +592,11 @@ extern const char *dev_driver_string(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
include/linux/dynamic_printk.h new file +96 -0
96 lines not on this page · raw message
include/linux/kernel.h +6 -1
@@ -14,6 +14,7 @@#include <linux/compiler.h> #include <linux/bitops.h> #include <linux/log2.h> +#include <linux/dynamic_printk.h> #include <asm/byteorder.h> #include <asm/bug.h>
@@ -288,8 +289,12 @@ extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type, #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
include/linux/module.h +4 -0
@@ -359,6 +359,10 @@ struct modulestruct marker *markers;unsigned int num_markers;#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +struct mod_debug *start_verbose; +unsigned int num_verbose; +#endif };#ifndef MODULE_ARCH_INIT #define MODULE_ARCH_INIT {}
kernel/module.c +22 -0
@@ -744,6 +744,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags) }/* Store the name of the last unloaded module for diagnostic purposes */ strlcpy (last_unloaded_module, mod->name,sizeof (last_unloaded_module)); +unregister_dynamic_debug_module (mod->name);free_module (mod); out:
@@ -1717,6 +1718,9 @@ static struct module *load_module(void __user *umod,unsigned int unusedgplcrcindex;unsigned int markersindex;unsigned int markersstringsindex; +unsigned int verboseindex; +struct mod_debug *iter; +unsigned long value;struct module *mod;long err =0 ;void *percpu =NULL , *ptr =NULL ;/* Stops spurious gcc warning */
@@ -1993,6 +1997,7 @@ static struct module *load_module(void __user *umod, markersindex =find_sec (hdr, sechdrs, secstrings,"__markers" ); markersstringsindex =find_sec (hdr, sechdrs, secstrings,"__markers_strings" ); + verboseindex =find_sec (hdr, sechdrs, secstrings,"__verbose" );/* Now do relocations. */ for (i =1 ; i < hdr->e_shnum; i++) {
@@ -2020,6 +2025,11 @@ static struct module *load_module(void __user *umod, mod->num_markers = sechdrs[markersindex].sh_size /sizeof (*mod->markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG + mod->start_verbose = (void *)sechdrs[verboseindex].sh_addr; + mod->num_verbose = sechdrs[verboseindex].sh_size / +sizeof (*mod->start_verbose); +#endif /* Find duplicate symbols */ err =verify_export_symbols (mod);
@@ -2043,6 +2053,18 @@ static struct module *load_module(void __user *umod,marker_update_probe_range (mod->markers, mod->markers + mod->num_markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +for (value = (unsigned long )mod->start_verbose; + value < (unsigned long )mod->start_verbose + + (unsigned long )(mod->num_verbose *sizeof (struct mod_debug )); + value +=sizeof (struct mod_debug )) { + iter = (struct mod_debug *)value; +register_dynamic_debug_module (iter->modname, + iter->type, + iter->logical_modname, + iter->flag_names, iter->hash, iter->hash2); + } +#endif err =module_finalize (hdr, sechdrs, mod);if (err <0 ) goto cleanup;
lib/Kconfig.debug +55 -0
61 lines not on this page · raw message
lib/Makefile +2 -0
@@ -70,6 +70,8 @@ lib-$(CONFIG_GENERIC_BUG) += bug.o obj-$(CONFIG_HAVE_LMB) += lmb.o +obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o + hostprogs-y := gen_crc32table clean-files := crc32table.h
lib/dynamic_printk.c new file +413 -0
413 lines not on this page · raw message
net/netfilter/nf_conntrack_pptp.c +1 -1
@@ -65,7 +65,7 @@ void struct nf_conntrack_expect *exp) __read_mostly;EXPORT_SYMBOL_GPL (nf_nat_pptp_hook_expectfn); -#ifdef DEBUG +#if defined(DEBUG ) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG )/* PptpControlMessageType names */ const char *const pptp_msg_name[] = { "UNKNOWN_MESSAGE",
scripts/Makefile.lib +10 -1
@@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") +#hash values +ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\ + -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))" +else +debug_flags = +endif + _c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o) _a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
@@ -120,7 +128,8 @@ endif c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__c_flags) $(modkern_cflags) \ - -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ + $(debug_flags) a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__a_flags) $(modkern_aflags)
scripts/basic/Makefile +1 -1
@@ -9,7 +9,7 @@ # fixdep: Used to generate dependency information during build process # docproc: Used in Documentation/DocBook -hostprogs-y := fixdep docproc +hostprogs-y := fixdep docproc hash always := $(hostprogs-y) # fixdep is needed to compile other host programs
scripts/basic/hash.c new file +64 -0
64 lines not on this page · raw message
Quoted 30 lines · Jason Baron
Quoted 14 lines · Greg KH
Quoted 13 lines · Jason Baron
Quoted 11 lines · Randy Dunlap
Quoted 6 lines · On Fri, 8 Aug 2008 17:51:53 -0400 Jason Baron wrote:
Few notes...there is still one control file: <debugfs>/dynamic_printk/modules We can split this up now or later, but I kind of like being able to see all the controls in one file. Also, i've used a djb2 hash function in the code, which i'm not sure is under the correct license/copyright, so i just wanted to point that out as well. see:
scripts/basic/hash.c. If its an issue, i can find another hash function.What license does it have? I don't see one.
Quoted 9 lines
Quoted 3 lines
hmmm...a search for djb2 finds a number of users, for example, i found this one which is covered by GPL2, http://www.telegraphics.com.au/svn/dpa/trunk/symtab.c
is that sufficient to say its ok?That's a tough call. I'd run that through the license board of your employer if you have any questions about this, as it is your name with their domain that is going to have the "signed-off-by:" pointing back to.
We're ok with the patch as is...i'm including an updated version below, which contains some documentation improvements...as you mentioned before, perhaps you can include this patch through the driver tree. It should apply with minimal munging, but please point me at a tree, if there are any issues.
Quoted 6 lines
thanks,
-Jason
Signed-off-by Jason Baron <[email protected]>
So close, can I have a good changelog comment with the patch so people know what it is when they look in the logs?
Care to resend it with that?
thanks,
greg k-h
Quoted 5 lines · Greg KH
So close, can I have a good changelog comment with the patch so people know what it is when they look in the logs?
Care to resend it with that?
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.
---
Documentation/kernel-parameters.txt | 5 include/asm-generic/vmlinux.lds.h | 10 + include/linux/device.h | 6 - include/linux/dynamic_printk.h | 96 ++++++++ include/linux/kernel.h | 7 + include/linux/module.h | 4 kernel/module.c | 22 ++ lib/Kconfig.debug | 55 +++++ lib/Makefile | 2 lib/dynamic_printk.c | 413 +++++++++++++++++++++++++++++++++++ net/netfilter/nf_conntrack_pptp.c | 2 scripts/Makefile.lib | 11 + scripts/basic/Makefile | 2 scripts/basic/hash.c | 64 +++++ 14 files changed, 693 insertions(+), 6 deletions(-) create mode 100644 include/linux/dynamic_printk.h create mode 100644 lib/dynamic_printk.c create mode 100644 scripts/basic/hash.c
Documentation/kernel-parameters.txt +5 -0
@@ -1580,6 +1580,11 @@ and is between 256 and 4096 characters. It is defined in the file autoconfiguration. Ranges are in pairs (memory base and size). + dynamic_printk + Enables pr_debug()/dev_dbg() calls if + CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also + be switched on/off via <debugfs>/dynamic_printk/modules + print-fatal-signals= [KNL] debug: print fatal signals print-fatal-signals=1: print segfault info to
include/asm-generic/vmlinux.lds.h +9 -1
@@ -249,7 +249,15 @@ CPU_DISCARD(init.data) \ CPU_DISCARD(init.rodata) \ MEM_DISCARD(init.data) \ - MEM_DISCARD(init.rodata) +MEM_DISCARD (init.rodata) \ + /* implement dynamic printk debug */ \ + VMLINUX_SYMBOL(__start___verbose_strings) = .; \ + *(__verbose_strings ) \ + VMLINUX_SYMBOL(__stop___verbose_strings) = .; \ + . = ALIGN(8); \ + VMLINUX_SYMBOL(__start___verbose) = .; \ + *(__verbose ) \ + VMLINUX_SYMBOL(__stop___verbose) = .;#define INIT_TEXT \ *(.init.text) \
include/linux/device.h +5 -1
@@ -592,7 +592,11 @@ extern const char *dev_driver_string(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
include/linux/dynamic_printk.h new file +96 -0
96 lines not on this page · raw message
include/linux/kernel.h +6 -1
@@ -14,6 +14,7 @@#include <linux/compiler.h> #include <linux/bitops.h> #include <linux/log2.h> +#include <linux/dynamic_printk.h> #include <asm/byteorder.h> #include <asm/bug.h>
@@ -288,8 +289,12 @@ extern void print_hex_dump_bytes(const char *prefix_str, int prefix_type, #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
include/linux/module.h +4 -0
@@ -359,6 +359,10 @@ struct modulestruct marker *markers;unsigned int num_markers;#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +struct mod_debug *start_verbose; +unsigned int num_verbose; +#endif };#ifndef MODULE_ARCH_INIT #define MODULE_ARCH_INIT {}
kernel/module.c +22 -0
@@ -744,6 +744,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags) }/* Store the name of the last unloaded module for diagnostic purposes */ strlcpy (last_unloaded_module, mod->name,sizeof (last_unloaded_module)); +unregister_dynamic_debug_module (mod->name);free_module (mod); out:
@@ -1717,6 +1718,9 @@ static struct module *load_module(void __user *umod,unsigned int unusedgplcrcindex;unsigned int markersindex;unsigned int markersstringsindex; +unsigned int verboseindex; +struct mod_debug *iter; +unsigned long value;struct module *mod;long err =0 ;void *percpu =NULL , *ptr =NULL ;/* Stops spurious gcc warning */
@@ -1993,6 +1997,7 @@ static struct module *load_module(void __user *umod, markersindex =find_sec (hdr, sechdrs, secstrings,"__markers" ); markersstringsindex =find_sec (hdr, sechdrs, secstrings,"__markers_strings" ); + verboseindex =find_sec (hdr, sechdrs, secstrings,"__verbose" );/* Now do relocations. */ for (i =1 ; i < hdr->e_shnum; i++) {
@@ -2020,6 +2025,11 @@ static struct module *load_module(void __user *umod, mod->num_markers = sechdrs[markersindex].sh_size /sizeof (*mod->markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG + mod->start_verbose = (void *)sechdrs[verboseindex].sh_addr; + mod->num_verbose = sechdrs[verboseindex].sh_size / +sizeof (*mod->start_verbose); +#endif /* Find duplicate symbols */ err =verify_export_symbols (mod);
@@ -2043,6 +2053,18 @@ static struct module *load_module(void __user *umod,marker_update_probe_range (mod->markers, mod->markers + mod->num_markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +for (value = (unsigned long )mod->start_verbose; + value < (unsigned long )mod->start_verbose + + (unsigned long )(mod->num_verbose *sizeof (struct mod_debug )); + value +=sizeof (struct mod_debug )) { + iter = (struct mod_debug *)value; +register_dynamic_debug_module (iter->modname, + iter->type, + iter->logical_modname, + iter->flag_names, iter->hash, iter->hash2); + } +#endif err =module_finalize (hdr, sechdrs, mod);if (err <0 ) goto cleanup;
lib/Kconfig.debug +55 -0
61 lines not on this page · raw message
lib/Makefile +2 -0
@@ -70,6 +70,8 @@ lib-$(CONFIG_GENERIC_BUG) += bug.o obj-$(CONFIG_HAVE_LMB) += lmb.o +obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o + hostprogs-y := gen_crc32table clean-files := crc32table.h
lib/dynamic_printk.c new file +413 -0
413 lines not on this page · raw message
net/netfilter/nf_conntrack_pptp.c +1 -1
@@ -65,7 +65,7 @@ void struct nf_conntrack_expect *exp) __read_mostly;EXPORT_SYMBOL_GPL (nf_nat_pptp_hook_expectfn); -#ifdef DEBUG +#if defined(DEBUG ) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG )/* PptpControlMessageType names */ const char *const pptp_msg_name[] = { "UNKNOWN_MESSAGE",
scripts/Makefile.lib +10 -1
@@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") +#hash values +ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\ + -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))" +else +debug_flags = +endif + _c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o) _a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
@@ -120,7 +128,8 @@ endif c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__c_flags) $(modkern_cflags) \ - -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ + $(debug_flags) a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__a_flags) $(modkern_aflags)
scripts/basic/Makefile +1 -1
@@ -9,7 +9,7 @@ # fixdep: Used to generate dependency information during build process # docproc: Used in Documentation/DocBook -hostprogs-y := fixdep docproc +hostprogs-y := fixdep docproc hash always := $(hostprogs-y) # fixdep is needed to compile other host programs
scripts/basic/hash.c new file +64 -0
64 lines not on this page · raw message
Quoted 8 lines · Jason Baron
Quoted 5 lines · Greg KH
So close, can I have a good changelog comment with the patch so people know what it is when they look in the logs?
Care to resend it with that?
Base infrastructure to enable per-module debug messages.
Ah, so close...
With this patch, I get the following build error:
CC [M] drivers/usb/gadget/u_ether.odrivers/usb/gadget/u_ether.c: In function ‘gether_setup’:drivers/usb/gadget/u_ether.c:787: error: ‘KBUILD_MODNAME’ undeclared (first use in this function) drivers/usb/gadget/u_ether.c:787: error: (Each undeclared identifier is reported only once drivers/usb/gadget/u_ether.c:787: error: for each function it appears in.)drivers/usb/gadget/u_ether.c:787: error: unknown field ‘Usage’ specified in initializer drivers/usb/gadget/u_ether.c:787: error: expected expression before ‘.’ tokendrivers/usb/gadget/u_ether.c:787: error: initializer element is not constantdrivers/usb/gadget/u_ether.c:787: error: (near initialization for ‘descriptor.hash’) drivers/usb/gadget/u_ether.c:787: error: ‘Usage’ undeclared (first use in this function) drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have ‘long long int’ and ‘char *’) drivers/usb/gadget/u_ether.c:787: error: expected ‘)’ before ‘:’ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have ‘long long int’ and ‘char *’) drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have ‘long long int’ and ‘char *’) drivers/usb/gadget/u_ether.c:787: error: expected ‘)’ before ‘:’ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have ‘long long int’ and ‘char *’) drivers/usb/gadget/u_ether.c:787: error: expected ‘)’ before ‘:’ tokendrivers/usb/gadget/u_ether.c:787: warning: passing argument 4 of ‘__dynamic_dbg_enabled_helper’ makes integer from pointer without a cast drivers/usb/gadget/u_ether.c:787: error: expected ‘)’ before ‘KBUILD_MODNAME’drivers/usb/gadget/u_ether.c:787: warning: too few arguments for format
make[1]: *** [drivers/usb/gadget/u_ether.o] Error 1
make: *** [_module_drivers/usb/gadget] Error 2
Did you try a simple 'make allmodconfig'?
Also, I cleaned it up a bit to make it pass checkpatch.pl and sparse, doesn't anyone run these things anymore...
I've attached my fixed up version below.
Any ideas?
thanks,
greg k-h
From: Jason Baron <[email protected]>
Date: Tue, 12 Aug 2008 16:46:19 -0400
Subject: driver core: basic infrastructure for per-module dynamic debug messages
To: Greg KH <[email protected]>
Cc: Randy Dunlap <[email protected]>, [email protected], [email protected], [email protected], [email protected]
Message-ID: <[email protected]>
Content-Disposition: inline
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.
--- Documentation/kernel-parameters.txt | 5 include/asm-generic/vmlinux.lds.h | 10 include/linux/device.h | 6 include/linux/dynamic_printk.h | 96 ++++++++ include/linux/kernel.h | 7 include/linux/module.h | 4 kernel/module.c | 22 + lib/Kconfig.debug | 55 ++++ lib/Makefile | 2 lib/dynamic_printk.c | 412 ++++++++++++++++++++++++++++++++++++ net/netfilter/nf_conntrack_pptp.c | 2 scripts/Makefile.lib | 11 scripts/basic/Makefile | 2 scripts/basic/hash.c | 64 +++++ 14 files changed, 692 insertions(+), 6 deletions(-)
Documentation/kernel-parameters.txt +5 -0
@@ -1675,6 +1675,11 @@ and is between 256 and 4096 characters. autoconfiguration. Ranges are in pairs (memory base and size). + dynamic_printk + Enables pr_debug()/dev_dbg() calls if + CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also + be switched on/off via <debugfs>/dynamic_printk/modules + print-fatal-signals= [KNL] debug: print fatal signals print-fatal-signals=1: print segfault info to
include/asm-generic/vmlinux.lds.h +9 -1
@@ -268,7 +268,15 @@ CPU_DISCARD(init.data) \ CPU_DISCARD(init.rodata) \ MEM_DISCARD(init.data) \ - MEM_DISCARD(init.rodata) +MEM_DISCARD (init.rodata) \ + /* implement dynamic printk debug */ \ + VMLINUX_SYMBOL(__start___verbose_strings) = .; \ + *(__verbose_strings ) \ + VMLINUX_SYMBOL(__stop___verbose_strings) = .; \ + . = ALIGN(8); \ + VMLINUX_SYMBOL(__start___verbose) = .; \ + *(__verbose ) \ + VMLINUX_SYMBOL(__stop___verbose) = .;#define INIT_TEXT \ *(.init.text) \
include/linux/device.h +5 -1
@@ -538,7 +538,11 @@ extern const char *dev_driver_string(con #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
include/linux/dynamic_printk.h new file +96 -0
96 lines not on this page · raw message
include/linux/kernel.h +6 -1
@@ -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 * #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
include/linux/module.h +4 -0
@@ -346,6 +346,10 @@ struct modulestruct module_ref ref[NR_CPUS ];#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +struct mod_debug *start_verbose; +unsigned int num_verbose; +#endif };#ifndef MODULE_ARCH_INIT #define MODULE_ARCH_INIT {}
kernel/module.c +22 -0
@@ -784,6 +784,7 @@ sys_delete_module(const char __user *nammutex_lock (&module_mutex);/* Store the name of the last unloaded module for diagnostic purposes */ strlcpy (last_unloaded_module, mod->name,sizeof (last_unloaded_module)); +unregister_dynamic_debug_module (mod->name);free_module (mod); out:
@@ -1831,6 +1832,9 @@ static struct module *load_module(void _#endif unsigned int markersindex;unsigned int markersstringsindex; +unsigned int verboseindex; +struct mod_debug *iter; +unsigned long value;struct module *mod;long err =0 ;void *percpu =NULL , *ptr =NULL ;/* Stops spurious gcc warning */
@@ -2117,6 +2121,7 @@ static struct module *load_module(void _ markersindex =find_sec (hdr, sechdrs, secstrings,"__markers" ); markersstringsindex =find_sec (hdr, sechdrs, secstrings,"__markers_strings" ); + verboseindex =find_sec (hdr, sechdrs, secstrings,"__verbose" );/* Now do relocations. */ for (i =1 ; i < hdr->e_shnum; i++) {
@@ -2144,6 +2149,11 @@ static struct module *load_module(void _ mod->num_markers = sechdrs[markersindex].sh_size /sizeof (*mod->markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG + mod->start_verbose = (void *)sechdrs[verboseindex].sh_addr; + mod->num_verbose = sechdrs[verboseindex].sh_size / +sizeof (*mod->start_verbose); +#endif /* Find duplicate symbols */ err =verify_export_symbols (mod);
@@ -2167,6 +2177,18 @@ static struct module *load_module(void _marker_update_probe_range (mod->markers, mod->markers + mod->num_markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +for (value = (unsigned long )mod->start_verbose; + value < (unsigned long )mod->start_verbose + + (unsigned long )(mod->num_verbose *sizeof (struct mod_debug )); + value +=sizeof (struct mod_debug )) { + iter = (struct mod_debug *)value; +register_dynamic_debug_module (iter->modname, + iter->type, + iter->logical_modname, + iter->flag_names, iter->hash, iter->hash2); + } +#endif err =module_finalize (hdr, sechdrs, mod);if (err <0 ) goto cleanup;
lib/dynamic_printk.c new file +412 -0
412 lines not on this page · raw message
lib/Kconfig.debug +55 -0
61 lines not on this page · raw message
lib/Makefile +2 -0
@@ -80,6 +80,8 @@ obj-$(CONFIG_HAVE_LMB) += lmb.o obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o +obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o + hostprogs-y := gen_crc32table clean-files := crc32table.h
net/netfilter/nf_conntrack_pptp.c +1 -1
@@ -65,7 +65,7 @@ void struct nf_conntrack_expect *exp) __read_mostly;EXPORT_SYMBOL_GPL (nf_nat_pptp_hook_expectfn); -#ifdef DEBUG +#if defined(DEBUG ) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG )/* PptpControlMessageType names */ const char *const pptp_msg_name[] = { "UNKNOWN_MESSAGE",
scripts/basic/hash.c new file +64 -0
64 lines not on this page · raw message
scripts/basic/Makefile +1 -1
@@ -9,7 +9,7 @@ # fixdep: Used to generate dependency information during build process # docproc: Used in Documentation/DocBook -hostprogs-y := fixdep docproc +hostprogs-y := fixdep docproc hash always := $(hostprogs-y) # fixdep is needed to compile other host programs
scripts/Makefile.lib +10 -1
@@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUI modname_flags = $(if $(filter 1,$(words $(modname))),\ -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") +#hash values +ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\ + -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))" +else +debug_flags = +endif + orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o) _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) _a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
@@ -121,7 +129,8 @@ endif c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__c_flags) $(modkern_cflags) \ - -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) + -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \ + $(debug_flags) a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \ $(__a_flags) $(modkern_aflags)
Andrew Morton
maintainerQuoted 25 lines · On Tue, 12 Aug 2008 18:08:04 -0700 Greg KH <[email protected]> wrote:
Quoted 8 lines · Jason Baron
Quoted 5 lines · Greg KH
So close, can I have a good changelog comment with the patch so people know what it is when they look in the logs?
Care to resend it with that?
Base infrastructure to enable per-module debug messages.
Ah, so close...
With this patch, I get the following build error:
CC [M]
drivers/usb/gadget/u_ether.odrivers/usb/gadget/u_ether.c: In function___gether_setup___:drivers/usb/gadget/u_ether.c:787: error:___KBUILD_MODNAME___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: (Each undeclared identifier is reported only oncedrivers/usb/gadget/u_ether.c:787: error: for each function it appears in.)drivers/usb/gadget/u_ether.c:787: error: unknown field___Usage___specified in initializerdrivers/usb/gadget/u_ether.c:787: error: expected expression before ___.___ tokendrivers/usb/gadget/u_ether.c:787: error: initializer element is not constantdrivers/usb/gadget/u_ether.c:787: error: (near initialization for ___descriptor.hash___)drivers/usb/gadget/u_ether.c:787: error:___Usage___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)
Quoted 8 lines
drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: warning: passing argument 4 of_____dynamic_dbg_enabled_helper___makes integer from pointer without a castdrivers/usb/gadget/u_ether.c:787: error: expected ___)___ before___KBUILD_MODNAME___
(lol at gcc crap)
Quoted 1 line
drivers/usb/gadget/u_ether.c:787: warning: too few arguments for format
argh, not that again. We had this with a patch from Jesse a while back, which I fixed thusly:
From: Andrew Morton <[email protected]>
alpha:
CC [M] drivers/usb/gadget/u_ether.o
In file included from include/asm/dma-mapping.h:7,
from include/linux/dma-mapping.h:52,
from include/linux/dmaengine.h:29,
from include/linux/skbuff.h:29,
from include/linux/if_ether.h:114,
from include/linux/etherdevice.h:27,
from drivers/usb/gadget/u_ether.c:29:include/linux/pci.h: In function 'pci_register_driver':include/linux/pci.h:673: error: 'KBUILD_MODNAME' undeclared (first use in this function) include/linux/pci.h:673: error: (Each undeclared identifier is reported only once include/linux/pci.h:673: error: for each function it appears in.)
Sam says:
The problem is that u_ether.o is used by two modules so when we build it KBUILD_MODNAME is not defined because kbuild does not know what value to use.
And in pci.h we have the following inline:
static inline int __must_check pci_register_driver(struct pci_driver *driver)
{
return __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
}And alpha uses dma-mapping.h to nullify a number of functions that seem to require something from pci.h.
Making it a macro seems to fix this.
---
include/linux/pci.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
include/linux/pci.h renamed from include/linux/pci.h~pci-make-pci_register_driver-a-macro +6 -4
@@ -680,10 +680,12 @@ void pci_enable_bridges(struct pci_bus */* Proper probing supporting hot-pluggable devices */ int __must_check __pci_register_driver (struct pci_driver *,struct module *,const char *mod_name); -static inline int __must_check pci_register_driver (struct pci_driver *driver) -{ -return __pci_register_driver (driver,THIS_MODULE ,KBUILD_MODNAME ); -} + +/* +* pci_register_driver must be a macro so that KBUILD_MODNAME can be expanded +*/ +#define pci_register_driver (driver) \ + __pci_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)void pci_unregister_driver (struct pci_driver *dev);void pci_remove_behind_bridge (struct pci_dev *dev);
_
Quoted 37 lines · Andrew Morton
Quoted 25 lines · On Tue, 12 Aug 2008 18:08:04 -0700 Greg KH <[email protected]> wrote:
Quoted 8 lines · Jason Baron
Quoted 5 lines · Greg KH
So close, can I have a good changelog comment with the patch so people know what it is when they look in the logs?
Care to resend it with that?
Base infrastructure to enable per-module debug messages.
Ah, so close...
With this patch, I get the following build error:
CC [M]
drivers/usb/gadget/u_ether.odrivers/usb/gadget/u_ether.c: In function___gether_setup___:drivers/usb/gadget/u_ether.c:787: error:___KBUILD_MODNAME___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: (Each undeclared identifier is reported only oncedrivers/usb/gadget/u_ether.c:787: error: for each function it appears in.)drivers/usb/gadget/u_ether.c:787: error: unknown field___Usage___specified in initializerdrivers/usb/gadget/u_ether.c:787: error: expected expression before ___.___ tokendrivers/usb/gadget/u_ether.c:787: error: initializer element is not constantdrivers/usb/gadget/u_ether.c:787: error: (near initialization for ___descriptor.hash___)drivers/usb/gadget/u_ether.c:787: error:___Usage___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)Quoted 8 lines
drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: warning: passing argument 4 of_____dynamic_dbg_enabled_helper___makes integer from pointer without a castdrivers/usb/gadget/u_ether.c:787: error: expected ___)___ before___KBUILD_MODNAME___
Quoted 6 lines
(lol at gcc crap)
Quoted 1 line
drivers/usb/gadget/u_ether.c:787: warning: too few arguments for formatargh, not that again. We had this with a patch from Jesse a while back, which I fixed thusly:
<patch moving KBUILD_MODNAME from a inline function to a macro snipped>
Yeah, I remember that too, but in this case, KBUILD_MODNAME is being used in a macro, not an inline function, the exact opposite.
Sam, any ideas here? I'll bounce the original patch at you if you missed it last time.
thanks,
greg k-h
Quoted 45 lines · Greg KH
Quoted 37 lines · Andrew Morton
Quoted 25 lines · On Tue, 12 Aug 2008 18:08:04 -0700 Greg KH <[email protected]> wrote:
Quoted 8 lines · Jason Baron
Quoted 5 lines · Greg KH
So close, can I have a good changelog comment with the patch so people know what it is when they look in the logs?
Care to resend it with that?
Base infrastructure to enable per-module debug messages.
Ah, so close...
With this patch, I get the following build error:
CC [M]
drivers/usb/gadget/u_ether.odrivers/usb/gadget/u_ether.c: In function___gether_setup___:drivers/usb/gadget/u_ether.c:787: error:___KBUILD_MODNAME___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: (Each undeclared identifier is reported only oncedrivers/usb/gadget/u_ether.c:787: error: for each function it appears in.)drivers/usb/gadget/u_ether.c:787: error: unknown field___Usage___specified in initializerdrivers/usb/gadget/u_ether.c:787: error: expected expression before ___.___ tokendrivers/usb/gadget/u_ether.c:787: error: initializer element is not constantdrivers/usb/gadget/u_ether.c:787: error: (near initialization for ___descriptor.hash___)drivers/usb/gadget/u_ether.c:787: error:___Usage___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)Quoted 8 lines
drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: warning: passing argument 4 of_____dynamic_dbg_enabled_helper___makes integer from pointer without a castdrivers/usb/gadget/u_ether.c:787: error: expected ___)___ before___KBUILD_MODNAME___Quoted 6 lines
(lol at gcc crap)
Quoted 1 line
drivers/usb/gadget/u_ether.c:787: warning: too few arguments for formatargh, not that again. We had this with a patch from Jesse a while back, which I fixed thusly:
Quoted 7 lines
<patch moving
KBUILD_MODNAMEfrom a inline function to a macro snipped>Yeah, I remember that too, but in this case,
KBUILD_MODNAMEis being used in a macro, not an inline function, the exact opposite.Sam, any ideas here? I'll bounce the original patch at you if you missed it last time.
I have not looked into the particular error but what happens is that u_ether.o is used by more than one module so kbuild does not know what value to assign the KBUILD_MODNAME and therefore decide not to assign KBUILD_MODNAME at all.
And because any usage of KBUILD_MODNAME is anyway flawed in u_ether.c as we do not know for what module it is being used it makes sense for kbuild to do so.
The above error happens because u_ether.c uses something that require KBUILD_MODNAME to be define.
So the correct fix is to avid usage of this macro in the source.
Note: The old error Andrew mentions was caused by alpha indirectly pulling in a inline function that used KBUILD_MODNAME - something that did not happen on the other architectures.
Sam
Quoted 67 lines · Sam Ravnborg
Quoted 45 lines · Greg KH
Quoted 37 lines · Andrew Morton
Quoted 25 lines · On Tue, 12 Aug 2008 18:08:04 -0700 Greg KH <[email protected]> wrote:
Quoted 8 lines · Jason Baron
Quoted 5 lines · Greg KH
So close, can I have a good changelog comment with the patch so people know what it is when they look in the logs?
Care to resend it with that?
Base infrastructure to enable per-module debug messages.
Ah, so close...
With this patch, I get the following build error:
CC [M]
drivers/usb/gadget/u_ether.odrivers/usb/gadget/u_ether.c: In function___gether_setup___:drivers/usb/gadget/u_ether.c:787: error:___KBUILD_MODNAME___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: (Each undeclared identifier is reported only oncedrivers/usb/gadget/u_ether.c:787: error: for each function it appears in.)drivers/usb/gadget/u_ether.c:787: error: unknown field___Usage___specified in initializerdrivers/usb/gadget/u_ether.c:787: error: expected expression before ___.___ tokendrivers/usb/gadget/u_ether.c:787: error: initializer element is not constantdrivers/usb/gadget/u_ether.c:787: error: (near initialization for ___descriptor.hash___)drivers/usb/gadget/u_ether.c:787: error:___Usage___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)Quoted 8 lines
drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: warning: passing argument 4 of_____dynamic_dbg_enabled_helper___makes integer from pointer without a castdrivers/usb/gadget/u_ether.c:787: error: expected ___)___ before___KBUILD_MODNAME___Quoted 6 lines
(lol at gcc crap)
Quoted 1 line
drivers/usb/gadget/u_ether.c:787: warning: too few arguments for formatargh, not that again. We had this with a patch from Jesse a while back, which I fixed thusly:
Quoted 7 lines
<patch moving
KBUILD_MODNAMEfrom a inline function to a macro snipped>Yeah, I remember that too, but in this case,
KBUILD_MODNAMEis being used in a macro, not an inline function, the exact opposite.Sam, any ideas here? I'll bounce the original patch at you if you missed it last time.
I have not looked into the particular error but what happens is that u_ether.o is used by more than one module so kbuild does not know what value to assign the
KBUILD_MODNAMEand therefore decide not to assignKBUILD_MODNAMEat all.And because any usage of
KBUILD_MODNAMEis anyway flawed inu_ether.cas we do not know for what module it is being used it makes sense for kbuild to do so.The above error happens because
u_ether.cuses something that requireKBUILD_MODNAMEto be define.
So the correct fix is to avid usage of this macro in the source.
Quoted 5 lines
Note: The old error Andrew mentions was caused by alpha indirectly pulling in a inline function that used
KBUILD_MODNAME- something that did not happen on the other architectures.Sam
the comment above KBUILD_MODNAME from scripts/Makefile.lib says:
# Note: It's possible that one object gets potentially linked into more
# than one module. In that case KBUILD_MODNAME will be set to # foo_bar, # where foo and bar are the name of the modules.
That seems like a reasonable behavior to me...but that is not what the code is doing...so at the very least the comment is wrong.
thanks,
-Jason
Quoted 51 lines · Sam Ravnborg
Quoted 50 lines · Greg KH
Quoted 37 lines · Andrew Morton
Quoted 25 lines · On Tue, 12 Aug 2008 18:08:04 -0700 Greg KH <[email protected]> wrote:
Quoted 8 lines · Jason Baron
Quoted 5 lines · Greg KH
So close, can I have a good changelog comment with the patch so people know what it is when they look in the logs?
Care to resend it with that?
Base infrastructure to enable per-module debug messages.
Ah, so close...
With this patch, I get the following build error:
CC [M]
drivers/usb/gadget/u_ether.odrivers/usb/gadget/u_ether.c: In function___gether_setup___:drivers/usb/gadget/u_ether.c:787: error:___KBUILD_MODNAME___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: (Each undeclared identifier is reported only oncedrivers/usb/gadget/u_ether.c:787: error: for each function it appears in.)drivers/usb/gadget/u_ether.c:787: error: unknown field___Usage___specified in initializerdrivers/usb/gadget/u_ether.c:787: error: expected expression before ___.___ tokendrivers/usb/gadget/u_ether.c:787: error: initializer element is not constantdrivers/usb/gadget/u_ether.c:787: error: (near initialization for ___descriptor.hash___)drivers/usb/gadget/u_ether.c:787: error:___Usage___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)Quoted 8 lines
drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: warning: passing argument 4 of_____dynamic_dbg_enabled_helper___makes integer from pointer without a castdrivers/usb/gadget/u_ether.c:787: error: expected ___)___ before___KBUILD_MODNAME___Quoted 6 lines
(lol at gcc crap)
Quoted 1 line
drivers/usb/gadget/u_ether.c:787: warning: too few arguments for formatargh, not that again. We had this with a patch from Jesse a while back, which I fixed thusly:
<patch moving
KBUILD_MODNAMEfrom a inline function to a macro snipped>Yeah, I remember that too, but in this case,
KBUILD_MODNAMEis being used in a macro, not an inline function, the exact opposite.
Quoted 7 lines
Quoted 2 lines
Sam, any ideas here? I'll bounce the original patch at you if you missed it last time.
I have not looked into the particular error but what happens is that u_ether.o is used by more than one module so kbuild does not know what value to assign the
KBUILD_MODNAMEand therefore decide not to assignKBUILD_MODNAMEat all.
Ick.
Hm, how do I fix this? Build u_ether.c into two different .o files, depending on which module it is being included into?
Or do:
#include "u_ether.c"
in the source code that was linking it in?
Actually, as ugly as that last one is, it probably would solve this issue, and be the same end-result, right?
thanks,
greg k-h
Quoted 65 lines · Greg KH
Quoted 51 lines · Sam Ravnborg
Quoted 50 lines · Greg KH
Quoted 37 lines · Andrew Morton
Quoted 25 lines · On Tue, 12 Aug 2008 18:08:04 -0700 Greg KH <[email protected]> wrote:
Quoted 8 lines · Jason Baron
Quoted 5 lines · Greg KH
So close, can I have a good changelog comment with the patch so people know what it is when they look in the logs?
Care to resend it with that?
Base infrastructure to enable per-module debug messages.
Ah, so close...
With this patch, I get the following build error:
CC [M]
drivers/usb/gadget/u_ether.odrivers/usb/gadget/u_ether.c: In function___gether_setup___:drivers/usb/gadget/u_ether.c:787: error:___KBUILD_MODNAME___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: (Each undeclared identifier is reported only oncedrivers/usb/gadget/u_ether.c:787: error: for each function it appears in.)drivers/usb/gadget/u_ether.c:787: error: unknown field___Usage___specified in initializerdrivers/usb/gadget/u_ether.c:787: error: expected expression before ___.___ tokendrivers/usb/gadget/u_ether.c:787: error: initializer element is not constantdrivers/usb/gadget/u_ether.c:787: error: (near initialization for ___descriptor.hash___)drivers/usb/gadget/u_ether.c:787: error:___Usage___undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)Quoted 8 lines
drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have___longlongint___and___char*___)drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ tokendrivers/usb/gadget/u_ether.c:787: warning: passing argument 4 of_____dynamic_dbg_enabled_helper___makes integer from pointer without a castdrivers/usb/gadget/u_ether.c:787: error: expected ___)___ before___KBUILD_MODNAME___Quoted 6 lines
(lol at gcc crap)
Quoted 1 line
drivers/usb/gadget/u_ether.c:787: warning: too few arguments for formatargh, not that again. We had this with a patch from Jesse a while back, which I fixed thusly:
<patch moving
KBUILD_MODNAMEfrom a inline function to a macro snipped>Yeah, I remember that too, but in this case,
KBUILD_MODNAMEis being used in a macro, not an inline function, the exact opposite.Quoted 7 lines
Quoted 2 lines
Sam, any ideas here? I'll bounce the original patch at you if you missed it last time.
I have not looked into the particular error but what happens is that u_ether.o is used by more than one module so kbuild does not know what value to assign the
KBUILD_MODNAMEand therefore decide not to assignKBUILD_MODNAMEat all.Ick.
Hm, how do I fix this? Build
u_ether.cinto two different .o files, depending on which module it is being included into?
Quoted 6 lines
Or do:
#include "u_ether.c"in the source code that was linking it in?
Actually, as ugly as that last one is, it probably would solve this issue, and be the same end-result, right?
Argh, that code is just horrible!!!
I'll go split this up into separate sub-modules, like it really needs to be. That will solve this problem.
Bah, why do people make things so hard...
thanks,
greg k-h
Quoted 38 lines · Greg KH
Quoted 8 lines · Jason Baron
Quoted 5 lines · Greg KH
So close, can I have a good changelog comment with the patch so people know what it is when they look in the logs?
Care to resend it with that?
Base infrastructure to enable per-module debug messages.
Ah, so close...
With this patch, I get the following build error:
CC [M]
drivers/usb/gadget/u_ether.odrivers/usb/gadget/u_ether.c: In function ‘gether_setup’:drivers/usb/gadget/u_ether.c:787: error: ‘KBUILD_MODNAME’ undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: (Each undeclared identifier is reported only oncedrivers/usb/gadget/u_ether.c:787: error: for each function it appears in.)drivers/usb/gadget/u_ether.c:787: error: unknown field ‘Usage’ specified in initializerdrivers/usb/gadget/u_ether.c:787: error: expected expression before ‘.’ tokendrivers/usb/gadget/u_ether.c:787: error: initializer element is not constantdrivers/usb/gadget/u_ether.c:787: error: (near initialization for ‘descriptor.hash’)drivers/usb/gadget/u_ether.c:787: error: ‘Usage’ undeclared (first use in this function)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have ‘long long int’ and ‘char *’)drivers/usb/gadget/u_ether.c:787: error: expected ‘)’ before ‘:’ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have ‘long long int’ and ‘char *’)drivers/usb/gadget/u_ether.c:787: error: invalid operands to binary << (have ‘long long int’ and ‘char *’)drivers/usb/gadget/u_ether.c:787: error: expected ‘)’ before ‘:’ tokendrivers/usb/gadget/u_ether.c:787: error: invalid operands to binary & (have ‘long long int’ and ‘char *’)drivers/usb/gadget/u_ether.c:787: error: expected ‘)’ before ‘:’ tokendrivers/usb/gadget/u_ether.c:787: warning: passing argument 4 of ‘__dynamic_dbg_enabled_helper’ makes integer from pointer without a castdrivers/usb/gadget/u_ether.c:787: error: expected ‘)’ before ‘KBUILD_MODNAME’drivers/usb/gadget/u_ether.c:787: warning: too few arguments for format
make[1]: *** [drivers/usb/gadget/u_ether.o] Error 1
make: *** [_module_drivers/usb/gadget] Error 2
Quoted 9 lines
Did you try a simple 'make allmodconfig'?
Also, I cleaned it up a bit to make it pass checkpatch.pl and sparse, doesn't anyone run these things anymore...
I've attached my fixed up version below.
Any ideas?
I was working on an older kernel and so i didn't see this error.
There seem to be a couple of issues here.
First, KBUILD_MODNAME is not defined during the compile of u_ether.c because it is included from multiple sources. It seems that when there are multiple sources "modname" is set to a string of all the source names with spaces in between. So something used in foo and bar looks like: "foo bar". From scripts/Makefile.lib:
# Note: It's possible that one object gets potentially linked into more
# than one module. In that case KBUILD_MODNAME will be set to foo_bar,
# where foo and bar are the name of the modules.
name-fix = $(subst $(comma),_,$(subst -,_,$1))basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
modname_flags = $(if $(filter 1,$(words $(modname))),\
-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))").
.
.
So, the comment says that the KBUILD_MODNAME should be set to "foo_bar" if its included from multiple files...however, the modname_flags definition is not doing that. In fact, if there are multiple sources its simply setting a NULL modname_flag. This issue is independent of the patchset I posted, and probably is best fixed separately. A patch which resolves this issue:
---
scripts/Makefile.lib +2 -1
@@ -94,7 +94,8 @@ obj-dirs := $(addprefix $(obj)/,$(obj-dirs)) name-fix = $(subst $(comma),_,$(subst -,_,$1)) basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))" modname_flags = $(if $(filter 1,$(words $(modname))),\ - -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") + -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))",\ + -D"KBUILD_MODNAME=KBUILD_STR($(subst $(space),_,$(call name-fix,$(modname))))") #hash values ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
The second issue is then that the hash functions that i introduced don't like these spaces either. So on top of the patch set i posted please add the patch below. The kernel should then compile. I tested this on the 'linux-next' tree, which did not boot on the system i was using, but i'm not sure it was related to this change.
thanks,
-Jason
---
scripts/Makefile.lib +2 -2
@@ -99,8 +99,8 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\ #hash values ifdef CONFIG_DYNAMIC_PRINTK_DEBUG -debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\ - -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))" +debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(subst $(space),_,$(modname)))"\ + -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(subst $(space),_,$(modname)))" else debug_flags = endif
Quoted 8 lines · Jason Baron
Quoted 5 lines · Greg KH
So close, can I have a good changelog comment with the patch so people know what it is when they look in the logs?
Care to resend it with that?
Base infrastructure to enable per-module debug messages.
<snip>
Ok, I got the build problem with the usb-gadget drivers all worked out now, and added this to my driver-core tree.
Very nice stuff, again, thanks for doing this. I'll work to clean up the USB drivers to all rely on this and not their separate CONFIG_USB_DEBUG option.
Also, would it make sense to add a patch like the one below to this code? It might be nice to know when each module's debugging value is manually changed by the user for the log files.
If you like it, I can merge it in the main patch.
thanks,
greg k-h
--- lib/dynamic_printk.c | 6 ++++++ 1 file changed, 6 insertions(+)
lib/dynamic_printk.c +6 -0
@@ -288,6 +288,9 @@ static ssize_t pr_debug_write(struct fil num_enabled++; dynamic_enabled =DYNAMIC_ENABLED_SOME ; err =0 ; +printk (KERN_DEBUG +"debugging enabled for module %s" , + elem->name); }else if (!value && (elem->enable ==1 )) { elem->enable =0 ; num_enabled--;
@@ -304,6 +307,9 @@ static ssize_t pr_debug_write(struct fil dynamic_enabled =DYNAMIC_ENABLED_NONE ; err =0 ; +printk (KERN_DEBUG +"debugging disabled for module " +"%s" , elem->name); } } }
Quoted 27 lines · Greg KH
Also, would it make sense to add a patch like the one below to this code? It might be nice to know when each module's debugging value is manually changed by the user for the log files.
If you like it, I can merge it in the main patch.
thanks,
greg k-h
--- lib/dynamic_printk.c | 6 ++++++ 1 file changed, 6 insertions(+)lib/dynamic_printk.c +3
-0@@ -288,6 +288,9 @@ static ssize_t pr_debug_write(struct fil num_enabled++; dynamic_enabled =DYNAMIC_ENABLED_SOME ; err =0 ; +printk (KERN_DEBUG +"debugging enabled for module %s" , + elem->name); }else if (!value && (elem->enable ==1 )) { elem->enable =0 ; num_enabled--;
lib/dynamic_printk.c static ssize_t pr_debug_write(struct fil · line 315
Quoted 9 lines
lib/dynamic_printk.c +3
-0@@ -304,6 +307,9 @@ static ssize_t pr_debug_write(struct fil dynamic_enabled =DYNAMIC_ENABLED_NONE ; err =0 ; +printk (KERN_DEBUG +"debugging disabled for module " +"%s" , elem->name); } } }
looks good. we might also want to add a message for the cases where are the modules are enabled/disabled too.
thanks,
-Jason
include/linux/module.h struct module · line 365
Quoted 10 lines · On Wednesday 16 July 2008 07:31:08 Jason Baron wrote:
include/linux/module.h +4
-0@@ -359,6 +359,10 @@ struct modulestruct marker *markers;unsigned int num_markers;#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG +struct mod_debug *start_verbose; +unsigned int num_verbose; +#endif
Hi Jason,
Couple of nit-picks about the module part of this patch. First, this could
just be called "verbose" rather than "start_verbose"...
Quoted 37 lines
include/linux/module.h +12
-0@@ -1717,6 +1718,9 @@ static struct module *load_module(void __user *umod,unsigned int unusedgplcrcindex;unsigned int markersindex;unsigned int markersstringsindex; +unsigned int verboseindex; +struct mod_debug *iter; +unsigned long value;struct module *mod;long err =0 ;void *percpu =NULL , *ptr =NULL ;/* Stops spurious gcc warning */ @@ -1993,6 +1997,7 @@ static struct module *load_module(void __user *umod, markersindex =find_sec (hdr, sechdrs, secstrings,"__markers" ); markersstringsindex =find_sec (hdr, sechdrs, secstrings,"__markers_strings" ); + verboseindex =find_sec (hdr, sechdrs, secstrings,"__verbose" );/* Now do relocations. */ for (i =1 ; i < hdr->e_shnum; i++) {@@ -2020,6 +2025,11 @@ static struct module *load_module(void __user *umod, mod->num_markers = sechdrs[markersindex].sh_size /sizeof (*mod->markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG + mod->start_verbose = (void *)sechdrs[verboseindex].sh_addr; + mod->num_verbose = sechdrs[verboseindex].sh_size / +sizeof (*mod->start_verbose); +#endif /* Find duplicate symbols */ err =verify_export_symbols (mod);@@ -2043,6 +2053,19 @@ static struct module *load_module(void __user *umod,marker_update_probe_range (mod->markers, mod->markers + mod->num_markers);#endif +#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG + for (value = (unsigned long)mod->start_verbose; + value < (unsigned long)mod->start_verbose +
include/linux/module.h static struct module *load_module(void __user *umod, · line 2068
Quoted 10 lines
include/linux/module.h +10
-0+ (unsigned long )(mod->num_verbose *sizeof (struct mod_debug )); + value += sizeof(struct mod_debug)) { + iter = (struct mod_debug *)value; +register_debug_module (iter->modname, +simple_strtoul (iter->type,NULL ,10 ), + iter->logical_modname, +simple_strtoul (iter->num_flags,NULL ,10 ), + iter->flag_names); + } +#endif
This loop seems way more complex than it needs to be. Perhaps pull these two out into a setup_verbose_debug() func which is a noop
for !CONFIG_DYNAMIC_PRINTK_DEBUG, and drop all the casts?
Thanks,
Rusty.