Skip to contentSkip to conversation

gcov: add gcov profiling infrastructure

PATCH In review Peter Oberparleiter 5 participants 7 messages May 19, 2008 – Jul 2, 2008

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 5/7 gcov: add gcov profiling infrastructure

From: Peter Oberparleiter <[email protected]>

gcov profiling infrastructure:

* change kbuild to include profiling flags
* provide functions needed by profiling code
* present profiling data as files in debugfs

---
 Documentation/gcov.txt              |  127 +++++
 Documentation/kernel-parameters.txt |    7 
 Makefile                            |   10 
 arch/Kconfig                        |    2 
 init/main.c                         |    8 
 kernel/Makefile                     |    1 
 kernel/gcov/Kconfig                 |   45 +
 kernel/gcov/Makefile                |    3 
 kernel/gcov/base.c                  |  145 ++++++
 kernel/gcov/fs.c                    |  609 ++++++++++++++++++++++++++
 kernel/gcov/gcc_3_4.c               |  420 +++++++++++++++++
 kernel/gcov/gcov.h                  |  128 +++++
 scripts/Makefile.lib                |    8 
 13 files changed, 1509 insertions(+), 4 deletions(-)
Makefile +6 -4
Index: linux-2.6.26-rc3/Makefile
===================================================================
@@ -320,6 +320,7 @@ AFLAGS_MODULE   = $(MODFLAGS)
 LDFLAGS_MODULE  =
 CFLAGS_KERNEL	=
 AFLAGS_KERNEL	=
+CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage
 
 
 # Use LINUXINCLUDE when you must reference the include/ directory.
@@ -345,7 +346,7 @@ export CPP AR NM STRIP OBJCOPY OBJDUMP M
 export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
 
 export KBUILD_CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
-export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+export KBUILD_CFLAGS CFLAGS_KERNEL CFLAGS_MODULE CFLAGS_GCOV
 export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
 
 # When compiling out-of-tree modules, put MODVERDIR in the module
@@ -1132,7 +1133,8 @@ clean: archclean $(clean-dirs)
 	@find . $(RCS_FIND_IGNORE) \
 		\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
 		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-		-o -name '*.symtypes' -o -name 'modules.order' \) \
+		-o -name '*.symtypes' -o -name 'modules.order' \
+		-o -name '*.gcno' \) \
 		-type f -print | xargs rm -f
 
 # mrproper - Delete all generated files, including .config
@@ -1336,8 +1338,8 @@ clean: $(clean-dirs)
 	$(call cmd,rmfiles)
 	@find $(KBUILD_EXTMOD) $(RCS_FIND_IGNORE) \
 		\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \
-		-type f -print | xargs rm -f
+		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
+		-o -name '*.gcno' \) -type f -print | xargs rm -f
 
 help:
 	@echo  '  Building external modules.'
scripts/Makefile.lib +8 -0
Index: linux-2.6.26-rc3/scripts/Makefile.lib
===================================================================
@@ -100,6 +100,14 @@ _c_flags       = $(KBUILD_CFLAGS) $(ccfl
 _a_flags       = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
 _cpp_flags     = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
 
+# Enable profiling flags for a file, directory or for all files depending on
+# variables GCOV_obj.o, GCOV and CONFIG_GCOV_PROFILE_ALL (in this order)
+ifeq ($(CONFIG_GCOV_PROFILE),y)
+_c_flags += $(if $(patsubst n%,, \
+		$(GCOV_$(basetarget).o)$(GCOV)$(CONFIG_GCOV_PROFILE_ALL)), \
+		$(CFLAGS_GCOV))
+endif
+
 # If building the kernel in a separate objtree expand all occurrences
 # of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
 
kernel/gcov/Kconfig new file +45 -0

45 lines not on this page · raw message

kernel/gcov/base.c new file +145 -0

145 lines not on this page · raw message

kernel/gcov/gcov.h new file +128 -0

128 lines not on this page · raw message

kernel/Makefile +1 -0
Index: linux-2.6.26-rc3/kernel/Makefile
===================================================================
@@ -69,6 +69,7 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayac
 obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
 obj-$(CONFIG_MARKERS) += marker.o
 obj-$(CONFIG_LATENCYTOP) += latencytop.o
+obj-$(CONFIG_GCOV_PROFILE) += gcov/
 
 ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y)
 # According to Alan Modra <[email protected]>, the -fno-omit-frame-pointer is
kernel/gcov/Makefile new file +3 -0
Index: linux-2.6.26-rc3/kernel/gcov/Makefile
===================================================================
@@ -0,0 +1,3 @@
+EXTRA_CFLAGS := -DSRCTREE='"$(srctree)"' -DOBJTREE='"$(objtree)"'
+
+obj-$(CONFIG_GCOV_PROFILE) := base.o fs.o gcc_3_4.o
kernel/gcov/fs.c new file +609 -0

609 lines not on this page · raw message

kernel/gcov/gcc_3_4.c new file +420 -0

420 lines not on this page · raw message

init/main.c +8 -0
Index: linux-2.6.26-rc3/init/main.c
===================================================================
@@ -80,6 +80,14 @@
 #warning gcc-4.1.0 is known to miscompile the kernel.  A different compiler version is recommended.
 #endif
 
+#ifdef CONFIG_GCOV_PROFILE
+
+#if GCC_VERSION_LOWER(3, 4)
+#error "GCOV profiling support for gcc versions below 3.4 not included"
+#endif /* GCC_VERSION_LOWER */
+
+#endif /* CONFIG_GCOV_PROFILE */
+
 static int kernel_init(void *);
 
 extern void init_IRQ(void);
Documentation/kernel-parameters.txt +7 -0
Index: linux-2.6.26-rc3/Documentation/kernel-parameters.txt
===================================================================
@@ -42,6 +42,7 @@ parameter is applicable:
 	EFI	EFI Partitioning (GPT) is enabled
 	EIDE	EIDE/ATAPI support is enabled.
 	FB	The frame buffer device is enabled.
+	GCOV	GCOV profiling is enabled.
 	HW	Appropriate hardware is enabled.
 	IA-64	IA-64 architecture is enabled.
 	IOSCHED	More than one I/O scheduler is enabled.
@@ -704,6 +705,12 @@ and is between 256 and 4096 characters. 
 			Format: off | on
 			default: on
 
+	gcov_persist=	[GCOV] When non-zero (default), profiling data for
+			kernel modules is saved and remains accessible via
+			debugfs, even when the module is unloaded/reloaded.
+			When zero, profiling data is discarded and associated
+			debugfs files are removed at module unload time.
+
 	gdth=		[HW,SCSI]
 			See header of drivers/scsi/gdth.c.
 
Documentation/gcov.txt new file +127 -0

127 lines not on this page · raw message

arch/Kconfig +2 -0
Index: linux-2.6.26-rc3/arch/Kconfig
===================================================================
@@ -39,3 +39,5 @@ config HAVE_KRETPROBES
 
 config HAVE_DMA_ATTRS
 	def_bool n
+
+source "kernel/gcov/Kconfig"
#1 lore raw

kernel/gcov/Kconfig line 43

Quoted 3 lines · On Mon, 19 May 2008 10:44:22 +0200 Peter Oberparleiter…
kernel/gcov/Kconfig new file +3 -0
+	Note that a kernel compiled with profiling flags will be significantly
+        larger and run slower. Also be sure to exclude files from profiling
+        which are not linked to the kernel image to prevent linker errors.

heh, it was all too much for mips.

{standard input}: Assembler messages:
{standard input}:2716: Error: Branch out of range
{standard input}:2819: Error: Branch out of range
{standard input}:2884: Error: Branch out of range
{standard input}:3032: Error: Branch out of range
{standard input}:3097: Error: Branch out of range
{standard input}:3151: Error: Branch out of range
{standard input}:3216: Error: Branch out of range
make[1]: *** [drivers/telephony/ixj.o] Error 1
make: *** [drivers/telephony/ixj.o] Error 2

#2 lore raw
Quoted 8 lines · Andrew Morton

kernel/gcov/Kconfig line 43

Quoted 3 lines · On Mon, 19 May 2008 10:44:22 +0200 Peter Oberparleiter…
kernel/gcov/Kconfig new file +3 -0
+	Note that a kernel compiled with profiling flags will be significantly
+        larger and run slower. Also be sure to exclude files from profiling
+        which are not linked to the kernel image to prevent linker errors.

heh, it was all too much for mips.

Quoted 10 lines

{standard input}: Assembler messages:
{standard input}:2716: Error: Branch out of range
{standard input}:2819: Error: Branch out of range
{standard input}:2884: Error: Branch out of range
{standard input}:3032: Error: Branch out of range
{standard input}:3097: Error: Branch out of range
{standard input}:3151: Error: Branch out of range
{standard input}:3216: Error: Branch out of range
make[1]: *** [drivers/telephony/ixj.o] Error 1
make: *** [drivers/telephony/ixj.o] Error 2

A known problem which I had decieded to ignore until it begins to actually bite. It's triggered by something like this

__asm__ __volatile__(
" .set mips3 \n"
"1: ll %0, %1 # atomic_add \n"
" addu %0, %2 \n"
" sc %0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));

when compiled into a large compilation unit.

Ralf

#3 lore raw
Quoted 20 lines · Ralf Baechle
Quoted 8 lines · Andrew Morton

kernel/gcov/Kconfig line 43

Quoted 3 lines · On Mon, 19 May 2008 10:44:22 +0200 Peter Oberparleiter…
kernel/gcov/Kconfig new file +3 -0
+	Note that a kernel compiled with profiling flags will be significantly
+        larger and run slower. Also be sure to exclude files from profiling
+        which are not linked to the kernel image to prevent linker errors.

heh, it was all too much for mips.

Quoted 10 lines

{standard input}: Assembler messages:
{standard input}:2716: Error: Branch out of range
{standard input}:2819: Error: Branch out of range
{standard input}:2884: Error: Branch out of range
{standard input}:3032: Error: Branch out of range
{standard input}:3097: Error: Branch out of range
{standard input}:3151: Error: Branch out of range
{standard input}:3216: Error: Branch out of range
make[1]: *** [drivers/telephony/ixj.o] Error 1
make: *** [drivers/telephony/ixj.o] Error 2

Quoted 2 lines

A known problem which I had decieded to ignore until it begins to actually bite.

I don't suppose there is an easy way to fix/work around this, is there?

#4 lore raw
In reply to Ralf Baechle
Quoted 27 lines · Ralf Baechle
Quoted 10 lines

{standard input}: Assembler messages:
{standard input}:2716: Error: Branch out of range
{standard input}:2819: Error: Branch out of range
{standard input}:2884: Error: Branch out of range
{standard input}:3032: Error: Branch out of range
{standard input}:3097: Error: Branch out of range
{standard input}:3151: Error: Branch out of range
{standard input}:3216: Error: Branch out of range
make[1]: *** [drivers/telephony/ixj.o] Error 1
make: *** [drivers/telephony/ixj.o] Error 2

A known problem which I had decieded to ignore until it begins to actually bite. It's triggered by something like this

__asm__ __volatile__(
" .set mips3 \n"
"1: ll %0, %1 # atomic_add \n"
" addu %0, %2 \n"
" sc %0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));

Quoted 1 line

when compiled into a large compilation unit.

Please unignore :) It bites when compiling madwifi (without profiling or anything such).

Marian

#5 lore raw
Quoted 28 lines · Marian Jancar
Quoted 27 lines · Ralf Baechle
Quoted 10 lines

{standard input}: Assembler messages:
{standard input}:2716: Error: Branch out of range
{standard input}:2819: Error: Branch out of range
{standard input}:2884: Error: Branch out of range
{standard input}:3032: Error: Branch out of range
{standard input}:3097: Error: Branch out of range
{standard input}:3151: Error: Branch out of range
{standard input}:3216: Error: Branch out of range
make[1]: *** [drivers/telephony/ixj.o] Error 1
make: *** [drivers/telephony/ixj.o] Error 2

A known problem which I had decieded to ignore until it begins to actually bite. It's triggered by something like this

__asm__ __volatile__(
" .set mips3 \n"
"1: ll %0, %1 # atomic_add \n"
" addu %0, %2 \n"
" sc %0, %1 \n"
" beqz %0, 2f \n"
" .subsection 2 \n"
"2: b 1b \n"
" .previous \n"
" .set mips0 \n"
: "=&r" (temp), "=m" (v->counter)
: "Ir" (i), "m" (v->counter));

Quoted 4 lines
Quoted 1 line

when compiled into a large compilation unit.

Please unignore :) It bites when compiling madwifi (without profiling or anything such).

Can't reproduce this one - what is the cooking receipe based on a recent devel kernel?

Ralf

#6 lore raw
In reply to Peter Oberparleiter
Quoted 7 lines · Peter Oberparleiter

From: Peter Oberparleiter <[email protected]>

gcov profiling infrastructure:

* change kbuild to include profiling flags
* provide functions needed by profiling code
* present profiling data as files in debugfs

Good stuff, thanks for finally pushing this upstream!

Regarding the use of debugfs, have you considered making your own file system independent of that? Currently, you'd need a lot of boilerplate code (basically a copy of debugs/inode.c), but I think it'd be appropriate since you're adding more than just a few simple files in debugfs.

Maybe we can talk next monday when I'm in the office, because some time ago, I have already started a patch set that would make it trivial to add a new debugfs-like file system.

	Arnd <><