Loading Documentation/ftrace.txt +79 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,8 @@ of ftrace. Here is a list of some of the key files: be traced. If a function exists in both set_ftrace_filter and set_ftrace_notrace, the function will _not_ be traced. set_ftrace_pid: Have the function tracer only trace a single thread. available_filter_functions: This lists the functions that ftrace has processed and can trace. These are the function names that you can pass to "set_ftrace_filter" or Loading Loading @@ -1073,6 +1075,83 @@ For simple one time traces, the above is sufficent. For anything else, a search through /proc/mounts may be needed to find where the debugfs file-system is mounted. Single thread tracing --------------------- By writing into /debug/tracing/set_ftrace_pid you can trace a single thread. For example: # cat /debug/tracing/set_ftrace_pid no pid # echo 3111 > /debug/tracing/set_ftrace_pid # cat /debug/tracing/set_ftrace_pid 3111 # echo function > /debug/tracing/current_tracer # cat /debug/tracing/trace | head # tracer: function # # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | yum-updatesd-3111 [003] 1637.254676: finish_task_switch <-thread_return yum-updatesd-3111 [003] 1637.254681: hrtimer_cancel <-schedule_hrtimeout_range yum-updatesd-3111 [003] 1637.254682: hrtimer_try_to_cancel <-hrtimer_cancel yum-updatesd-3111 [003] 1637.254683: lock_hrtimer_base <-hrtimer_try_to_cancel yum-updatesd-3111 [003] 1637.254685: fget_light <-do_sys_poll yum-updatesd-3111 [003] 1637.254686: pipe_poll <-do_sys_poll # echo -1 > /debug/tracing/set_ftrace_pid # cat /debug/tracing/trace |head # tracer: function # # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | ##### CPU 3 buffer started #### yum-updatesd-3111 [003] 1701.957688: free_poll_entry <-poll_freewait yum-updatesd-3111 [003] 1701.957689: remove_wait_queue <-free_poll_entry yum-updatesd-3111 [003] 1701.957691: fput <-free_poll_entry yum-updatesd-3111 [003] 1701.957692: audit_syscall_exit <-sysret_audit yum-updatesd-3111 [003] 1701.957693: path_put <-audit_syscall_exit If you want to trace a function when executing, you could use something like this simple program: #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int main (int argc, char **argv) { if (argc < 1) exit(-1); if (fork() > 0) { int fd, ffd; char line[64]; int s; ffd = open("/debug/tracing/current_tracer", O_WRONLY); if (ffd < 0) exit(-1); write(ffd, "nop", 3); fd = open("/debug/tracing/set_ftrace_pid", O_WRONLY); s = sprintf(line, "%d\n", getpid()); write(fd, line, s); write(ffd, "function", 8); close(fd); close(ffd); execvp(argv[1], argv+1); } return 0; } dynamic ftrace -------------- Loading arch/x86/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ config X86 select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_RET_TRACER if X86_32 select HAVE_FUNCTION_GRAPH_TRACER if X86_32 select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) select HAVE_ARCH_KGDB if !X86_VOYAGER Loading arch/x86/include/asm/ftrace.h +2 −2 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ struct dyn_arch_ftrace { #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_FUNCTION_RET_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifndef __ASSEMBLY__ Loading @@ -51,6 +51,6 @@ struct ftrace_ret_stack { extern void return_to_handler(void); #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_RET_TRACER */ #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ #endif /* _ASM_X86_FTRACE_H */ arch/x86/kernel/Makefile +2 −2 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ CFLAGS_REMOVE_paravirt-spinlocks.o = -pg CFLAGS_REMOVE_ftrace.o = -pg endif ifdef CONFIG_FUNCTION_RET_TRACER ifdef CONFIG_FUNCTION_GRAPH_TRACER # Don't trace __switch_to() but let it for function tracer CFLAGS_REMOVE_process_32.o = -pg endif Loading Loading @@ -70,7 +70,7 @@ obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_RET_TRACER) += ftrace.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o Loading arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +4 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <linux/cpufreq.h> #include <linux/compiler.h> #include <linux/dmi.h> #include <linux/ftrace.h> #include <linux/acpi.h> #include <acpi/processor.h> Loading Loading @@ -391,6 +392,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, unsigned int next_perf_state = 0; /* Index into perf table */ unsigned int i; int result = 0; struct power_trace it; dprintk("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu); Loading Loading @@ -427,6 +429,8 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, } } trace_power_mark(&it, POWER_PSTATE, next_perf_state); switch (data->cpu_feature) { case SYSTEM_INTEL_MSR_CAPABLE: cmd.type = SYSTEM_INTEL_MSR_CAPABLE; Loading Loading
Documentation/ftrace.txt +79 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,8 @@ of ftrace. Here is a list of some of the key files: be traced. If a function exists in both set_ftrace_filter and set_ftrace_notrace, the function will _not_ be traced. set_ftrace_pid: Have the function tracer only trace a single thread. available_filter_functions: This lists the functions that ftrace has processed and can trace. These are the function names that you can pass to "set_ftrace_filter" or Loading Loading @@ -1073,6 +1075,83 @@ For simple one time traces, the above is sufficent. For anything else, a search through /proc/mounts may be needed to find where the debugfs file-system is mounted. Single thread tracing --------------------- By writing into /debug/tracing/set_ftrace_pid you can trace a single thread. For example: # cat /debug/tracing/set_ftrace_pid no pid # echo 3111 > /debug/tracing/set_ftrace_pid # cat /debug/tracing/set_ftrace_pid 3111 # echo function > /debug/tracing/current_tracer # cat /debug/tracing/trace | head # tracer: function # # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | yum-updatesd-3111 [003] 1637.254676: finish_task_switch <-thread_return yum-updatesd-3111 [003] 1637.254681: hrtimer_cancel <-schedule_hrtimeout_range yum-updatesd-3111 [003] 1637.254682: hrtimer_try_to_cancel <-hrtimer_cancel yum-updatesd-3111 [003] 1637.254683: lock_hrtimer_base <-hrtimer_try_to_cancel yum-updatesd-3111 [003] 1637.254685: fget_light <-do_sys_poll yum-updatesd-3111 [003] 1637.254686: pipe_poll <-do_sys_poll # echo -1 > /debug/tracing/set_ftrace_pid # cat /debug/tracing/trace |head # tracer: function # # TASK-PID CPU# TIMESTAMP FUNCTION # | | | | | ##### CPU 3 buffer started #### yum-updatesd-3111 [003] 1701.957688: free_poll_entry <-poll_freewait yum-updatesd-3111 [003] 1701.957689: remove_wait_queue <-free_poll_entry yum-updatesd-3111 [003] 1701.957691: fput <-free_poll_entry yum-updatesd-3111 [003] 1701.957692: audit_syscall_exit <-sysret_audit yum-updatesd-3111 [003] 1701.957693: path_put <-audit_syscall_exit If you want to trace a function when executing, you could use something like this simple program: #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int main (int argc, char **argv) { if (argc < 1) exit(-1); if (fork() > 0) { int fd, ffd; char line[64]; int s; ffd = open("/debug/tracing/current_tracer", O_WRONLY); if (ffd < 0) exit(-1); write(ffd, "nop", 3); fd = open("/debug/tracing/set_ftrace_pid", O_WRONLY); s = sprintf(line, "%d\n", getpid()); write(fd, line, s); write(ffd, "function", 8); close(fd); close(ffd); execvp(argv[1], argv+1); } return 0; } dynamic ftrace -------------- Loading
arch/x86/Kconfig +1 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ config X86 select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_RET_TRACER if X86_32 select HAVE_FUNCTION_GRAPH_TRACER if X86_32 select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) select HAVE_ARCH_KGDB if !X86_VOYAGER Loading
arch/x86/include/asm/ftrace.h +2 −2 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ struct dyn_arch_ftrace { #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_FUNCTION_RET_TRACER #ifdef CONFIG_FUNCTION_GRAPH_TRACER #ifndef __ASSEMBLY__ Loading @@ -51,6 +51,6 @@ struct ftrace_ret_stack { extern void return_to_handler(void); #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_RET_TRACER */ #endif /* CONFIG_FUNCTION_GRAPH_TRACER */ #endif /* _ASM_X86_FTRACE_H */
arch/x86/kernel/Makefile +2 −2 Original line number Diff line number Diff line Loading @@ -14,7 +14,7 @@ CFLAGS_REMOVE_paravirt-spinlocks.o = -pg CFLAGS_REMOVE_ftrace.o = -pg endif ifdef CONFIG_FUNCTION_RET_TRACER ifdef CONFIG_FUNCTION_GRAPH_TRACER # Don't trace __switch_to() but let it for function tracer CFLAGS_REMOVE_process_32.o = -pg endif Loading Loading @@ -70,7 +70,7 @@ obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_RET_TRACER) += ftrace.o obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o Loading
arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c +4 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <linux/cpufreq.h> #include <linux/compiler.h> #include <linux/dmi.h> #include <linux/ftrace.h> #include <linux/acpi.h> #include <acpi/processor.h> Loading Loading @@ -391,6 +392,7 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, unsigned int next_perf_state = 0; /* Index into perf table */ unsigned int i; int result = 0; struct power_trace it; dprintk("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu); Loading Loading @@ -427,6 +429,8 @@ static int acpi_cpufreq_target(struct cpufreq_policy *policy, } } trace_power_mark(&it, POWER_PSTATE, next_perf_state); switch (data->cpu_feature) { case SYSTEM_INTEL_MSR_CAPABLE: cmd.type = SYSTEM_INTEL_MSR_CAPABLE; Loading