Discussion:
[RFC PATCH 09/22 -v2] mcount tracer show task comm and pid
Steven Rostedt
2008-01-09 23:29:23 UTC
Permalink
This adds the task comm and pid to the trace output. This gives the
output like:

CPU 0: sshd:2605 [<ffffffff80251858>] remove_wait_queue+0xc/0x4a <-- [<ffffffff802ad7be>] free_poll_entry+0x1e/0x2a
CPU 2: bash:2610 [<ffffffff8038c3aa>] tty_check_change+0x9/0xb6 <-- [<ffffffff8038d295>] tty_ioctl+0x59f/0xcdd
CPU 0: sshd:2605 [<ffffffff80491ec6>] _spin_lock_irqsave+0xe/0x81 <-- [<ffffffff80251863>] remove_wait_queue+0x17/0x4a
CPU 2: bash:2610 [<ffffffff8024e2f7>] find_vpid+0x9/0x24 <-- [<ffffffff8038d325>] tty_ioctl+0x62f/0xcdd
CPU 0: sshd:2605 [<ffffffff804923ec>] _spin_unlock_irqrestore+0x9/0x3a <-- [<ffffffff80251891>] remove_wait_queue+0x45/0x4a
CPU 0: sshd:2605 [<ffffffff802a18b3>] fput+0x9/0x1b <-- [<ffffffff802ad7c6>] free_poll_entry+0x26/0x2a


Signed-off-by: Steven Rostedt <***@redhat.com>
---
lib/tracing/tracer.c | 6 +++++-
lib/tracing/tracer.h | 3 +++
2 files changed, 8 insertions(+), 1 deletion(-)

Index: linux-compile-i386.git/lib/tracing/tracer.c
===================================================================
--- linux-compile-i386.git.orig/lib/tracing/tracer.c 2008-01-09 14:12:52.000000000 -0500
+++ linux-compile-i386.git/lib/tracing/tracer.c 2008-01-09 15:17:39.000000000 -0500
@@ -34,6 +34,7 @@ mctracer_add_trace_entry(struct mctracer
{
unsigned long idx, idx_next;
struct mctracer_entry *entry;
+ struct task_struct *tsk = current;

idx = tr->trace_idx[cpu];
idx_next = idx + 1;
@@ -52,6 +53,8 @@ mctracer_add_trace_entry(struct mctracer
entry->idx = atomic_inc_return(&tr->cnt);
entry->ip = ip;
entry->parent_ip = parent_ip;
+ entry->pid = tsk->pid;
+ memcpy(entry->comm, tsk->comm, TASK_COMM_LEN);
}

static notrace void trace_function(const unsigned long ip,
@@ -217,7 +220,8 @@ static int s_show(struct seq_file *m, vo
if (iter->ent == NULL) {
seq_printf(m, "mctracer:\n");
} else {
- seq_printf(m, " CPU %d: ", iter->cpu);
+ seq_printf(m, "CPU %d: ", iter->cpu);
+ seq_printf(m, "%s:%d ", iter->ent->comm, iter->ent->pid);
seq_print_ip_sym(m, iter->ent->ip);
if (iter->ent->parent_ip) {
seq_printf(m, " <-- ");
Index: linux-compile-i386.git/lib/tracing/tracer.h
===================================================================
--- linux-compile-i386.git.orig/lib/tracing/tracer.h 2008-01-09 14:11:35.000000000 -0500
+++ linux-compile-i386.git/lib/tracing/tracer.h 2008-01-09 15:17:39.000000000 -0500
@@ -2,11 +2,14 @@
#define _LINUX_MCOUNT_TRACER_H

#include <asm/atomic.h>
+#include <linux/sched.h>

struct mctracer_entry {
unsigned long idx;
unsigned long ip;
unsigned long parent_ip;
+ char comm[TASK_COMM_LEN];
+ pid_t pid;
};

struct mctracer_trace {
--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Steven Rostedt
2008-01-09 23:29:16 UTC
Permalink
Mark with "notrace" functions in core code that should not be
traced. The "notrace" attribute will prevent gcc from adding
a call to mcount on the annotated funtions.

Signed-off-by: Arnaldo Carvalho de Melo <***@ghostprotocols.net>
Signed-off-by: Steven Rostedt <***@redhat.com>

---
lib/smp_processor_id.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

Index: linux-compile-i386.git/lib/smp_processor_id.c
===================================================================
--- linux-compile-i386.git.orig/lib/smp_processor_id.c 2008-01-09 14:09:36.000000000 -0500
+++ linux-compile-i386.git/lib/smp_processor_id.c 2008-01-09 14:10:11.000000000 -0500
@@ -7,7 +7,7 @@
#include <linux/kallsyms.h>
#include <linux/sched.h>

-unsigned int debug_smp_processor_id(void)
+notrace unsigned int debug_smp_processor_id(void)
{
unsigned long preempt_count = preempt_count();
int this_cpu = raw_smp_processor_id();
--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Steven Rostedt
2008-01-09 23:29:28 UTC
Permalink
The get_monotonic_cycles needs to produce a monotonic counter as output.

This patch adds a cycle_raw to produce an accumulative counter.
Unfortunately there is already an cycle_accumulate variable, but that is
used to avoid clock source overflow and can also be decremented
(probably that name should be changed and we should use that for this
patch).


Signed-off-by: Steven Rostedt <***@goodmis.org>
Acked-by: John Stultz <***@us.ibm.com>

---
include/linux/clocksource.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

Index: linux-compile-i386.git/include/linux/clocksource.h
===================================================================
--- linux-compile-i386.git.orig/include/linux/clocksource.h 2008-01-09 14:23:29.000000000 -0500
+++ linux-compile-i386.git/include/linux/clocksource.h 2008-01-09 15:17:31.000000000 -0500
@@ -87,7 +87,7 @@ struct clocksource {
* more than one cache line.
*/
struct {
- cycle_t cycle_last, cycle_accumulated;
+ cycle_t cycle_last, cycle_accumulated, cycle_raw;
} ____cacheline_aligned_in_smp;

u64 xtime_nsec;
@@ -204,6 +204,7 @@ static inline void clocksource_accumulat
cycle_t offset = (now - cs->cycle_last) & cs->mask;
cs->cycle_last = now;
cs->cycle_accumulated += offset;
+ cs->cycle_raw += offset;
}

/**
--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Steven Rostedt
2008-01-09 23:29:26 UTC
Permalink
For better cacheline performance, this patch creates a separate
struct for each CPU with the percpu data grouped together.

Signed-off-by: Steven Rostedt <***@redhat.com>
---
lib/tracing/tracer.c | 42 +++++++++++++++++++++++-------------------
lib/tracing/tracer.h | 12 ++++++++----
2 files changed, 31 insertions(+), 23 deletions(-)

Index: linux-compile-i386.git/lib/tracing/tracer.c
===================================================================
--- linux-compile-i386.git.orig/lib/tracing/tracer.c 2008-01-09 14:14:43.000000000 -0500
+++ linux-compile-i386.git/lib/tracing/tracer.c 2008-01-09 15:17:28.000000000 -0500
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/linkage.h>
#include <linux/seq_file.h>
+#include <linux/percpu.h>
#include <linux/debugfs.h>
#include <linux/kallsyms.h>
#include <linux/uaccess.h>
@@ -25,6 +26,7 @@
#include "tracer_interface.h"

static struct mctracer_trace mctracer_trace;
+static DEFINE_PER_CPU(struct mctracer_trace_cpu, mctracer_trace_cpu);

static inline notrace void
mctracer_add_trace_entry(struct mctracer_trace *tr,
@@ -35,21 +37,22 @@ mctracer_add_trace_entry(struct mctracer
unsigned long idx, idx_next;
struct mctracer_entry *entry;
struct task_struct *tsk = current;
+ struct mctracer_trace_cpu *data = tr->data[cpu];

- idx = tr->trace_idx[cpu];
+ idx = data->trace_idx;
idx_next = idx + 1;

if (unlikely(idx_next >= tr->entries)) {
- atomic_inc(&tr->underrun[cpu]);
+ atomic_inc(&data->underrun);
idx_next = 0;
}

- tr->trace_idx[cpu] = idx_next;
+ data->trace_idx = idx_next;

- if (unlikely(idx_next != 0 && atomic_read(&tr->underrun[cpu])))
- atomic_inc(&tr->underrun[cpu]);
+ if (unlikely(idx_next != 0 && atomic_read(&data->underrun)))
+ atomic_inc(&data->underrun);

- entry = tr->trace[cpu] + idx * MCTRACER_ENTRY_SIZE;
+ entry = data->trace + idx * MCTRACER_ENTRY_SIZE;
entry->idx = atomic_inc_return(&tr->cnt);
entry->ip = ip;
entry->parent_ip = parent_ip;
@@ -69,11 +72,11 @@ static notrace void trace_function(const

tr = &mctracer_trace;

- atomic_inc(&tr->disabled[cpu]);
- if (likely(atomic_read(&tr->disabled[cpu]) == 1))
+ atomic_inc(&tr->data[cpu]->disabled);
+ if (likely(atomic_read(&tr->data[cpu]->disabled) == 1))
mctracer_add_trace_entry(tr, cpu, ip, parent_ip);

- atomic_dec(&tr->disabled[cpu]);
+ atomic_dec(&tr->data[cpu]->disabled);

raw_local_irq_restore(flags);
}
@@ -83,8 +86,8 @@ static notrace void mctracer_reset(struc
int cpu;

for_each_online_cpu(cpu) {
- tr->trace_idx[cpu] = 0;
- atomic_set(&tr->underrun[cpu], 0);
+ tr->data[cpu]->trace_idx = 0;
+ atomic_set(&tr->data[cpu]->underrun, 0);
}
}

@@ -105,16 +108,16 @@ static struct mctracer_entry *mctracer_e
unsigned long idx,
int cpu)
{
- struct mctracer_entry *array = tr->trace[cpu];
+ struct mctracer_entry *array = tr->data[cpu]->trace;
unsigned long underrun;

if (idx >= tr->entries)
return NULL;

- underrun = atomic_read(&tr->underrun[cpu]);
+ underrun = atomic_read(&tr->data[cpu]->underrun);
if (underrun)
idx = ((underrun - 1) + idx) % tr->entries;
- else if (idx >= tr->trace_idx[cpu])
+ else if (idx >= tr->data[cpu]->trace_idx)
return NULL;

return &array[idx];
@@ -129,7 +132,7 @@ static void *find_next_entry(struct mctr
int i;

for_each_possible_cpu(i) {
- if (!tr->trace[i])
+ if (!tr->data[i]->trace)
continue;
ent = mctracer_entry_idx(tr, iter->next_idx[i], i);
if (ent && (!next || next->idx > ent->idx)) {
@@ -452,6 +455,7 @@ static notrace int mctracer_alloc_buffer
int i;

for_each_possible_cpu(i) {
+ mctracer_trace.data[i] = &per_cpu(mctracer_trace_cpu, i);
array = (struct mctracer_entry *)
__get_free_pages(GFP_KERNEL, order);
if (array == NULL) {
@@ -459,7 +463,7 @@ static notrace int mctracer_alloc_buffer
" %ld bytes for trace buffer!\n", size);
goto free_buffers;
}
- mctracer_trace.trace[i] = array;
+ mctracer_trace.data[i]->trace = array;
}

/*
@@ -478,10 +482,10 @@ static notrace int mctracer_alloc_buffer

free_buffers:
for (i-- ; i >= 0; i--) {
- if (mctracer_trace.trace[i]) {
- free_pages((unsigned long)mctracer_trace.trace[i],
+ if (mctracer_trace.data[i] && mctracer_trace.data[i]->trace) {
+ free_pages((unsigned long)mctracer_trace.data[i]->trace,
order);
- mctracer_trace.trace[i] = NULL;
+ mctracer_trace.data[i]->trace = NULL;
}
}
return -ENOMEM;
Index: linux-compile-i386.git/lib/tracing/tracer.h
===================================================================
--- linux-compile-i386.git.orig/lib/tracing/tracer.h 2008-01-09 14:14:02.000000000 -0500
+++ linux-compile-i386.git/lib/tracing/tracer.h 2008-01-09 15:17:28.000000000 -0500
@@ -12,15 +12,19 @@ struct mctracer_entry {
pid_t pid;
};

+struct mctracer_trace_cpu {
+ void *trace;
+ unsigned long trace_idx;
+ atomic_t disabled;
+ atomic_t underrun;
+};
+
struct mctracer_trace {
- void *trace[NR_CPUS];
- unsigned long trace_idx[NR_CPUS];
unsigned long entries;
long ctrl;
unsigned long iter_flags;
atomic_t cnt;
- atomic_t disabled[NR_CPUS];
- atomic_t underrun[NR_CPUS];
+ struct mctracer_trace_cpu *data[NR_CPUS];
};

#endif /* _LINUX_MCOUNT_TRACER_H */
--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Steven Rostedt
2008-01-09 23:29:15 UTC
Permalink
If CONFIG_MCOUNT is selected and /proc/sys/kernel/mcount_enabled is set to a
non-zero value the mcount routine will be called everytime we enter a kernel
function that is not marked with the "notrace" attribute.

The mcount routine will then call a registered function if a function
happens to be registered.

[This code has been highly hacked by Steven Rostedt, so don't
blame Arnaldo for all of this ;-) ]

Signed-off-by: Arnaldo Carvalho de Melo <***@ghostprotocols.net>
Signed-off-by: Steven Rostedt <***@redhat.com>
---
Makefile | 4 ++
arch/x86/Kconfig | 4 ++
arch/x86/kernel/Makefile_32 | 1
arch/x86/kernel/entry_64.S | 40 ++++++++++++++++++++
arch/x86/kernel/mcount-wrapper.S | 25 ++++++++++++
include/linux/linkage.h | 2 +
include/linux/mcount.h | 21 ++++++++++
kernel/sysctl.c | 11 +++++
lib/Kconfig.debug | 2 +
lib/Makefile | 2 +
lib/tracing/Kconfig | 7 +++
lib/tracing/Makefile | 3 +
lib/tracing/mcount.c | 77 +++++++++++++++++++++++++++++++++++++++
13 files changed, 199 insertions(+)
create mode 100644 arch/i386/kernel/mcount-wrapper.S
create mode 100644 lib/tracing/Kconfig
create mode 100644 lib/tracing/Makefile
create mode 100644 lib/tracing/mcount.c
create mode 100644 lib/tracing/mcount.h

Index: linux-compile-i386.git/Makefile
===================================================================
--- linux-compile-i386.git.orig/Makefile 2008-01-09 14:09:36.000000000 -0500
+++ linux-compile-i386.git/Makefile 2008-01-09 14:10:07.000000000 -0500
@@ -509,6 +509,10 @@ endif

include $(srctree)/arch/$(SRCARCH)/Makefile

+# MCOUNT expects frame pointer
+ifdef CONFIG_MCOUNT
+KBUILD_CFLAGS += -pg
+endif
ifdef CONFIG_FRAME_POINTER
KBUILD_CFLAGS += -fno-omit-frame-pointer -fno-optimize-sibling-calls
else
Index: linux-compile-i386.git/arch/x86/Kconfig
===================================================================
--- linux-compile-i386.git.orig/arch/x86/Kconfig 2008-01-09 14:09:36.000000000 -0500
+++ linux-compile-i386.git/arch/x86/Kconfig 2008-01-09 14:10:07.000000000 -0500
@@ -28,6 +28,10 @@ config GENERIC_CMOS_UPDATE
bool
default y

+config ARCH_HAS_MCOUNT
+ bool
+ default y
+
config CLOCKSOURCE_WATCHDOG
bool
default y
Index: linux-compile-i386.git/arch/x86/kernel/Makefile_32
===================================================================
--- linux-compile-i386.git.orig/arch/x86/kernel/Makefile_32 2008-01-09 14:09:36.000000000 -0500
+++ linux-compile-i386.git/arch/x86/kernel/Makefile_32 2008-01-09 14:10:07.000000000 -0500
@@ -23,6 +23,7 @@ obj-$(CONFIG_APM) += apm_32.o
obj-$(CONFIG_X86_SMP) += smp_32.o smpboot_32.o tsc_sync.o
obj-$(CONFIG_SMP) += smpcommon_32.o
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline_32.o
+obj-$(CONFIG_MCOUNT) += mcount-wrapper.o
obj-$(CONFIG_X86_MPPARSE) += mpparse_32.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic_32.o nmi_32.o
obj-$(CONFIG_X86_IO_APIC) += io_apic_32.o
Index: linux-compile-i386.git/arch/x86/kernel/mcount-wrapper.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-compile-i386.git/arch/x86/kernel/mcount-wrapper.S 2008-01-09 14:10:07.000000000 -0500
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/x86/mcount-wrapper.S
+ *
+ * Copyright (C) 2004 Ingo Molnar
+ */
+
+.globl mcount
+mcount:
+ cmpl $0, mcount_enabled
+ jz out
+
+ push %ebp
+ mov %esp, %ebp
+ pushl %eax
+ pushl %ecx
+ pushl %edx
+
+ call __mcount
+
+ popl %edx
+ popl %ecx
+ popl %eax
+ popl %ebp
+out:
+ ret
Index: linux-compile-i386.git/include/linux/linkage.h
===================================================================
--- linux-compile-i386.git.orig/include/linux/linkage.h 2008-01-09 14:09:36.000000000 -0500
+++ linux-compile-i386.git/include/linux/linkage.h 2008-01-09 14:10:07.000000000 -0500
@@ -3,6 +3,8 @@

#include <asm/linkage.h>

+#define notrace __attribute__((no_instrument_function))
+
#ifdef __cplusplus
#define CPP_ASMLINKAGE extern "C"
#else
Index: linux-compile-i386.git/kernel/sysctl.c
===================================================================
--- linux-compile-i386.git.orig/kernel/sysctl.c 2008-01-09 14:09:36.000000000 -0500
+++ linux-compile-i386.git/kernel/sysctl.c 2008-01-09 14:10:07.000000000 -0500
@@ -46,6 +46,7 @@
#include <linux/nfs_fs.h>
#include <linux/acpi.h>
#include <linux/reboot.h>
+#include <linux/mcount.h>

#include <asm/uaccess.h>
#include <asm/processor.h>
@@ -470,6 +471,16 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = &proc_dointvec,
},
+#ifdef CONFIG_MCOUNT
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "mcount_enabled",
+ .data = &mcount_enabled,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec,
+ },
+#endif
#ifdef CONFIG_KMOD
{
.ctl_name = KERN_MODPROBE,
Index: linux-compile-i386.git/lib/Kconfig.debug
===================================================================
--- linux-compile-i386.git.orig/lib/Kconfig.debug 2008-01-09 14:09:36.000000000 -0500
+++ linux-compile-i386.git/lib/Kconfig.debug 2008-01-09 14:10:07.000000000 -0500
@@ -517,4 +517,6 @@ config FAULT_INJECTION_STACKTRACE_FILTER
help
Provide stacktrace filter for fault-injection capabilities

+source lib/tracing/Kconfig
+
source "samples/Kconfig"
Index: linux-compile-i386.git/lib/Makefile
===================================================================
--- linux-compile-i386.git.orig/lib/Makefile 2008-01-09 14:09:36.000000000 -0500
+++ linux-compile-i386.git/lib/Makefile 2008-01-09 14:10:07.000000000 -0500
@@ -66,6 +66,8 @@ obj-$(CONFIG_AUDIT_GENERIC) += audit.o
obj-$(CONFIG_SWIOTLB) += swiotlb.o
obj-$(CONFIG_FAULT_INJECTION) += fault-inject.o

+obj-$(CONFIG_MCOUNT) += tracing/
+
lib-$(CONFIG_GENERIC_BUG) += bug.o

hostprogs-y := gen_crc32table
Index: linux-compile-i386.git/lib/tracing/Kconfig
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-compile-i386.git/lib/tracing/Kconfig 2008-01-09 15:17:48.000000000 -0500
@@ -0,0 +1,7 @@
+
+# MCOUNT itself is useless, or will just be added overhead.
+# It needs something to register a function with it.
+config MCOUNT
+ bool
+ depends on DEBUG_KERNEL
+ select FRAME_POINTER
Index: linux-compile-i386.git/lib/tracing/Makefile
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-compile-i386.git/lib/tracing/Makefile 2008-01-09 15:17:48.000000000 -0500
@@ -0,0 +1,3 @@
+obj-$(CONFIG_MCOUNT) += libmcount.o
+
+libmcount-y := mcount.o
Index: linux-compile-i386.git/lib/tracing/mcount.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-compile-i386.git/lib/tracing/mcount.c 2008-01-09 14:10:07.000000000 -0500
@@ -0,0 +1,77 @@
+/*
+ * Infrastructure for profiling code inserted by 'gcc -pg'.
+ *
+ * Copyright (C) 2007 Arnaldo Carvalho de Melo <***@redhat.com>
+ *
+ * Converted to be more generic:
+ * Copyright (C) 2007-2008 Steven Rostedt <***@redhat.com>
+ *
+ * From code in the latency_tracer, that is:
+ *
+ * Copyright (C) 2004-2006 Ingo Molnar
+ * Copyright (C) 2004 William Lee Irwin III
+ */
+
+#include <linux/module.h>
+#include <linux/mcount.h>
+
+/*
+ * Since we have nothing protecting between the test of
+ * mcount_trace_function and the call to it, we can't
+ * set it to NULL without risking a race that will have
+ * the kernel call the NULL pointer. Instead, we just
+ * set the function pointer to a dummy function.
+ */
+notrace void dummy_mcount_tracer(unsigned long ip,
+ unsigned long parent_ip)
+{
+ /* do nothing */
+}
+
+mcount_func_t mcount_trace_function __read_mostly = dummy_mcount_tracer;
+int mcount_enabled __read_mostly;
+
+/** __mcount - hook for profiling
+ *
+ * This routine is called from the arch specific mcount routine, that in turn is
+ * called from code inserted by gcc -pg.
+ */
+notrace void __mcount(void)
+{
+ mcount_trace_function(CALLER_ADDR1, CALLER_ADDR2);
+}
+EXPORT_SYMBOL_GPL(mcount);
+/*
+ * The above EXPORT_SYMBOL is for the gcc call of mcount and not the
+ * function __mcount that it is underneath. I put the export there
+ * to fool checkpatch.pl. It wants that export to be with the
+ * function, but that function happens to be in assembly.
+ */
+
+/**
+ * register_mcount_function - register a function for profiling
+ * @func - the function for profiling.
+ *
+ * Register a function to be called by all functions in the
+ * kernel.
+ *
+ * Note: @func and all the functions it calls must be labeled
+ * with "notrace", otherwise it will go into a
+ * recursive loop.
+ */
+int register_mcount_function(mcount_func_t func)
+{
+ mcount_trace_function = func;
+ return 0;
+}
+
+/**
+ * clear_mcount_function - reset the mcount function
+ *
+ * This NULLs the mcount function and in essence stops
+ * tracing. There may be lag
+ */
+void clear_mcount_function(void)
+{
+ mcount_trace_function = dummy_mcount_tracer;
+}
Index: linux-compile-i386.git/include/linux/mcount.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ linux-compile-i386.git/include/linux/mcount.h 2008-01-09 15:17:20.000000000 -0500
@@ -0,0 +1,21 @@
+#ifndef _LINUX_MCOUNT_H
+#define _LINUX_MCOUNT_H
+
+#ifdef CONFIG_MCOUNT
+extern int mcount_enabled;
+
+#include <linux/linkage.h>
+
+#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
+#define CALLER_ADDR1 ((unsigned long)__builtin_return_address(1))
+#define CALLER_ADDR2 ((unsigned long)__builtin_return_address(2))
+
+typedef void (*mcount_func_t)(unsigned long ip, unsigned long parent_ip);
+
+extern void mcount(void);
+
+int register_mcount_function(mcount_func_t func);
+void clear_mcount_function(void);
+
+#endif /* CONFIG_MCOUNT */
+#endif /* _LINUX_MCOUNT_H */
Index: linux-compile-i386.git/arch/x86/kernel/entry_64.S
===================================================================
--- linux-compile-i386.git.orig/arch/x86/kernel/entry_64.S 2008-01-09 14:09:36.000000000 -0500
+++ linux-compile-i386.git/arch/x86/kernel/entry_64.S 2008-01-09 14:10:07.000000000 -0500
@@ -53,6 +53,46 @@

.code64

+#ifdef CONFIG_MCOUNT
+
+ENTRY(mcount)
+ cmpl $0, mcount_enabled
+ jz out
+
+ push %rbp
+ mov %rsp,%rbp
+
+ push %r11
+ push %r10
+ push %r9
+ push %r8
+ push %rdi
+ push %rsi
+ push %rdx
+ push %rcx
+ push %rax
+
+ mov 0x0(%rbp),%rax
+ mov 0x8(%rbp),%rdi
+ mov 0x8(%rax),%rsi
+
+ call *mcount_trace_function
+
+ pop %rax
+ pop %rcx
+ pop %rdx
+ pop %rsi
+ pop %rdi
+ pop %r8
+ pop %r9
+ pop %r10
+ pop %r11
+
+ pop %rbp
+out:
+ ret
+#endif
+
#ifndef CONFIG_PREEMPT
#define retint_kernel retint_restore_args
#endif
--
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Sam Ravnborg
2008-01-10 18:28:28 UTC
Permalink
Hi Steven.
Post by Steven Rostedt
Index: linux-compile-i386.git/arch/x86/Kconfig
===================================================================
--- linux-compile-i386.git.orig/arch/x86/Kconfig 2008-01-09 14:09:36.000000000 -0500
+++ linux-compile-i386.git/arch/x86/Kconfig 2008-01-09 14:10:07.000000000 -0500
@@ -28,6 +28,10 @@ config GENERIC_CMOS_UPDATE
bool
default y
+config ARCH_HAS_MCOUNT
+ bool
+ default y
+
Please use the following scheme:

arch/x86/Kconfig:
config X86
+ select HAVE_MCOUNT

lib/tracing/Kconfig

+ # ARCH shall select HAVE_MCOUNT if they provide this function
+ config HAVE_MCOUNT
+ bool
+
+ config MCOUNT
+ bool
+ select FRAME_POINTER

And then in your later patches:
+config MCOUNT_TRACER
+ bool "Profiler instrumentation based tracer"
+ depends on DEBUG_KERNEL && HAVE_MCOUNT
+ select MCOUNT
+ help
+ Use profiler....

The "default n" is a noop since this is the default.
And note that the depends on is remov