Skip to contentSkip to conversation

dynamic debug v2 - infrastructure

PATCH In review Jason Baron 7 participants 29 messages Jul 15, 2008 – Sep 16, 2008

Subsystems (9)
Networking Documentation Kbuild PCI +5 more subsystems
lore
Share & tools
lore
#0 lore raw

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
index bf6303e..d9a1245 100644
@@ -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
index f054778..799a8b5 100644
@@ -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
index 1a06026..fb03dbc 100644
@@ -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
index cd6d02c..3f99327 100644
@@ -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
index 819c4e8..74a2e32 100644
@@ -359,6 +359,10 @@ struct module
 	struct 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
index 8d6cccc..5f36555 100644
@@ -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
index bf8000f..78ab656 100644
@@ -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
index 97e54b0..7fea304 100644
@@ -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
index 8e44023..bb635ae 100644
@@ -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
index 4c324a1..0955995 100644
@@ -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

#1 lore raw
Quoted 7 lines · Jason Baron
include/linux/device.h +0 -0
index 1a06026..fb03dbc 100644
@@ -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

#2 lore raw
Quoted 24 lines · Greg KH

Return-Path: <[email protected]>

Quoted 7 lines · Jason Baron
include/linux/device.h +0 -0
index 1a06026..fb03dbc 100644
@@ -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 within kernel.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

#3 lore raw
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
index 1a06026..fb03dbc 100644
@@ -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.

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
+#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 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

#4 lore raw

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

#5 lore raw
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

#6 lore raw
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

#7 lore raw
In reply to Greg KH
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
index 1a06026..fb03dbc 100644
@@ -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.

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
+#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 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

#8 lore raw
In reply to Greg KH
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
index bf6303e..7c60e89 100644
@@ -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
index f054778..00804e0 100644
@@ -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
index 1a06026..fb03dbc 100644
@@ -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
index cd6d02c..25d09b8 100644
@@ -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
index 819c4e8..74a2e32 100644
@@ -359,6 +359,10 @@ struct module
 	struct 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
index 8d6cccc..ad7a105 100644
@@ -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
index bf8000f..78ab656 100644
@@ -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
index 97e54b0..7fea304 100644
@@ -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
index 8e44023..1e393cf 100644
@@ -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
index 4c324a1..0955995 100644
@@ -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

#9 lore raw
Quoted 6 lines · Jason Baron

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...

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 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 
+	  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

#10 lore raw
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 1

What'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

#11 lore raw
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

#12 lore raw
In reply to Jason Baron
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.c
lib/Kconfig.debug +0 -0
index 623ef24..6664783 100644
@@ -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
new file mode 100644
index 0000000..04ae7e2
@@ -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
new file mode 100644
index 0000000..3299ad7
@@ -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/

#13 lore raw
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

#14 lore raw
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

#15 lore raw
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
index bf6303e..7c60e89 100644
@@ -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
index f054778..00804e0 100644
@@ -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
index 1a06026..fb03dbc 100644
@@ -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
index cd6d02c..25d09b8 100644
@@ -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
index 819c4e8..74a2e32 100644
@@ -359,6 +359,10 @@ struct module
 	struct 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
index 8d6cccc..ad7a105 100644
@@ -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
index bf8000f..78ab656 100644
@@ -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
index 97e54b0..7fea304 100644
@@ -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
index 8e44023..1e393cf 100644
@@ -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
index 4c324a1..0955995 100644
@@ -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

#16 lore raw
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

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

#17 lore raw
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
index bf6303e..7c60e89 100644
@@ -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
index f054778..00804e0 100644
@@ -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
index 1a06026..fb03dbc 100644
@@ -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
index cd6d02c..25d09b8 100644
@@ -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
index 819c4e8..74a2e32 100644
@@ -359,6 +359,10 @@ struct module
 	struct 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
index 8d6cccc..ad7a105 100644
@@ -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
index bf8000f..78ab656 100644
@@ -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
index 97e54b0..7fea304 100644
@@ -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
index 8e44023..1e393cf 100644
@@ -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
index 4c324a1..0955995 100644
@@ -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

#18 lore raw
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.o
drivers/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 ‘.’ token
drivers/usb/gadget/u_ether.c:787: error: initializer element is not constant
drivers/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 ‘:’ token
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: invalid operands to binary << (have ‘long long int’ and ‘char *’) drivers/usb/gadget/u_ether.c:787: error: expected ‘)’ before ‘:’ token
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 ‘:’ token
drivers/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 module
 	struct 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 *nam
 	mutex_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)
maintainer
#19 lore raw
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.o
drivers/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 ___.___ token drivers/usb/gadget/u_ether.c:787: error: initializer element is not constant drivers/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 *___)

Quoted 8 lines

drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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: invalid operands to binary << (have ___long long int___ and ___char *___) drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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 ___:___ token
drivers/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___

(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.

Cc Jesse Barnes <[email protected]>
Cc Sam Ravnborg <[email protected]>
Cc Greg KH <[email protected]>

---

 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
diff -puN include/linux/pci.h~pci-make-pci_register_driver-a-macro include/linux/pci.h
@@ -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);

_

#20 lore raw
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.o
drivers/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 ___.___ token drivers/usb/gadget/u_ether.c:787: error: initializer element is not constant drivers/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 *___)

Quoted 8 lines

drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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: invalid operands to binary << (have ___long long int___ and ___char *___) drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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 ___:___ token
drivers/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___

Quoted 6 lines

(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:

<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

#21 lore raw
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.o
drivers/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 ___.___ token drivers/usb/gadget/u_ether.c:787: error: initializer element is not constant drivers/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 *___)

Quoted 8 lines

drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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: invalid operands to binary << (have ___long long int___ and ___char *___) drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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 ___:___ token
drivers/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___

Quoted 6 lines

(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:

Quoted 7 lines

<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.

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

#22 lore raw
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.o
drivers/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 ___.___ token drivers/usb/gadget/u_ether.c:787: error: initializer element is not constant drivers/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 *___)

Quoted 8 lines

drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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: invalid operands to binary << (have ___long long int___ and ___char *___) drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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 ___:___ token
drivers/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___

Quoted 6 lines

(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:

Quoted 7 lines

<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.

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.

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

#23 lore raw
In reply to Sam Ravnborg
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.o
drivers/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 ___.___ token drivers/usb/gadget/u_ether.c:787: error: initializer element is not constant drivers/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 *___)

Quoted 8 lines

drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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: invalid operands to binary << (have ___long long int___ and ___char *___) drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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 ___:___ token
drivers/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___

Quoted 6 lines

(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:

<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.

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_MODNAME and therefore decide not to assign KBUILD_MODNAME at 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

#24 lore raw
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.o
drivers/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 ___.___ token drivers/usb/gadget/u_ether.c:787: error: initializer element is not constant drivers/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 *___)

Quoted 8 lines

drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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: invalid operands to binary << (have ___long long int___ and ___char *___) drivers/usb/gadget/u_ether.c:787: error: expected ___)___ before ___:___ token
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 ___:___ token
drivers/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___

Quoted 6 lines

(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:

<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.

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_MODNAME and therefore decide not to assign KBUILD_MODNAME at 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?

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

#25 lore raw
In reply to Greg KH
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.o
drivers/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 ‘.’ token
drivers/usb/gadget/u_ether.c:787: error: initializer element is not constant
drivers/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 ‘:’ token
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: invalid operands to binary << (have ‘long long int’ and ‘char *’) drivers/usb/gadget/u_ether.c:787: error: expected ‘)’ before ‘:’ token
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 ‘:’ token
drivers/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

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
index b4ca38a..639d5dc 100644
@@ -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
index 639d5dc..3b5455b 100644
@@ -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
#26 lore raw
In reply to Jason Baron
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);
 				}
 			}
 		}
#27 lore raw
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

#28 lore raw
In reply to Jason Baron

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 module
 	struct 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.