mips-specific ftrace support
Subsystems (5)
PATCH v3 1/1 mips-specific ftrace support
From: Wu Zhangjin <[email protected]>
ftrace is a mcount based kernel tracing tool/framework, which is originally from RT_PREEMPT(http://rt.wiki.kernel.org).
ftrace is short for function tracer, this is its original name, but now, it becomes a kernel tracing framework, lots of kernel tracers are built on it, such as irqoff tracer, wakeup tracer and so forth. these tracers are arch-independent(?), but some of them are arch-dependent, such as the original
ftrace: function tracer, and dynamic function tracer, function graph tracer, and also, system call tracer.
here is the mips porting of these four arch-dependent tracers, it will enable the following new kernel config options in linux-mips system.
kernel hacking --->
Tracers -->
[*] Kernel Function Tracer
[*] Kernel Function Graph Tracer
...
[*] Trace syscalls
...
[*] enable/disable ftrace tracepoints dynamically
in reality, because the timestamp getting function are arch-dependent, lots of the tracers are arch-dependent. the arch-dependent part is that: sched_clock(). the original sched_clock() in mips is jiffes based, only give 10ms precision in 1000HZ, which is not enough for ftrace. to get high-precise timestamp, we must implement a new native_sched_clock() via reading the MIPS clock counter, but since it is only 32bit long, so, overflow should be handled carefully.
this -v3 patch series is based on the -v2 patch series and incorporates the feedback from Steven Rostedt and Thomas Gleixner.
!!NOTE!!
this -v3 not support modules yet, really hope this can be fixed in -v4 patch.
read the following document, and play with it:
Documentation/trace/ftrace.txt
Wu Zhangjin (7):
mips static function tracer support
add an endian argument to scripts/recordmcount.pl mips dynamic function tracer support
filter local function prefixed by $L
mips function graph tracer support
mips specific clock function to get precise timestamp mips specific system call tracer
arch/mips/Kconfig | 7 + arch/mips/Makefile | 2 + arch/mips/include/asm/ftrace.h | 35 ++++- arch/mips/include/asm/ptrace.h | 2 + arch/mips/include/asm/reg.h | 5 + arch/mips/include/asm/syscall.h | 84 +++++++++ arch/mips/include/asm/thread_info.h | 5 +- arch/mips/kernel/Makefile | 12 ++ arch/mips/kernel/csrc-r4k.c | 2 +- arch/mips/kernel/entry.S | 2 +- arch/mips/kernel/ftrace.c | 344 +++++++++++++++++++++++++++++++++++ arch/mips/kernel/ftrace_clock.c | 71 +++++++ arch/mips/kernel/mcount.S | 184 +++++++++++++++++++ arch/mips/kernel/mips_ksyms.c | 5 + arch/mips/kernel/ptrace.c | 14 ++- arch/mips/kernel/scall64-o32.S | 2 +- arch/mips/kernel/vmlinux.lds.S | 1 + kernel/trace/trace_clock.c | 2 +- scripts/Makefile.build | 1 + scripts/recordmcount.pl | 30 +++- 20 files changed, 799 insertions(+), 11 deletions(-) create mode 100644 arch/mips/include/asm/syscall.h create mode 100644 arch/mips/kernel/ftrace.c create mode 100644 arch/mips/kernel/ftrace_clock.c create mode 100644 arch/mips/kernel/mcount.S
PATCH v3 1/1 mips static function tracer support
From: Wu Zhangjin <[email protected]>
if -pg of gcc is enabled. a calling to _mcount will be inserted to each kernel function. so, there is a possibility to trace the functions in _mcount.
here is the implementation of mips specific _mcount for static function tracer.
-ffunction-sections option not works with -pg, so disable it if enables FUNCTION_TRACER.
--- arch/mips/Kconfig | 2 + arch/mips/Makefile | 2 + arch/mips/include/asm/ftrace.h | 25 ++++++++++- arch/mips/kernel/Makefile | 7 +++ arch/mips/kernel/mcount.S | 98 ++++++++++++++++++++++++++++++++++++++++ arch/mips/kernel/mips_ksyms.c | 5 ++ 6 files changed, 138 insertions(+), 1 deletions(-) create mode 100644 arch/mips/kernel/mcount.S
arch/mips/Kconfig +2 -0
@@ -4,6 +4,8 @@ config MIPS select HAVE_IDE select HAVE_OPROFILE select HAVE_ARCH_KGDB + select HAVE_FUNCTION_TRACER + select HAVE_FUNCTION_TRACE_MCOUNT_TEST # Horrible source of confusion. Die, die, die ... select EMBEDDED select RTC_LIB
arch/mips/Makefile +2 -0
@@ -48,7 +48,9 @@ ifneq ($(SUBARCH),$(ARCH)) endif endif +ifndef CONFIG_FUNCTION_TRACER cflags-y := -ffunction-sections +endif cflags-y += $(call cc-option, -mno-check-zero-division) ifdef CONFIG_32BIT
arch/mips/include/asm/ftrace.h +24 -1
@@ -1 +1,24 @@ -/* empty */ +/* +* This file is subject to the terms and conditions of the GNU General Public +* License. See the file "COPYING" in the main directory of this archive for +* more details. +* +* Copyright (C) 2009 DSLab, Lanzhou University, China +* Author: Wu Zhangjin <[email protected]> +*/ + +#ifndef _ASM_MIPS_FTRACE_H +#define _ASM_MIPS_FTRACE_H + +#ifdef CONFIG_FUNCTION_TRACER + +#define MCOUNT_ADDR ((unsigned long)(_mcount)) +#define MCOUNT_INSN_SIZE 4/* sizeof mcount call */ + +#ifndef __ASSEMBLY__ +extern void _mcount (void ); +#define mcount _mcount + +#endif /* __ASSEMBLY__ */ +#endif /* CONFIG_FUNCTION_TRACER */ +#endif /* _ASM_MIPS_FTRACE_H */
arch/mips/kernel/Makefile +7 -0
@@ -8,6 +8,11 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ptrace.o reset.o setup.o signal.o syscall.o \ time.o topology.o traps.o unaligned.o watch.o +ifdef CONFIG_FUNCTION_TRACER +# Do not profile debug and lowlevel utilities +CFLAGS_REMOVE_early_printk.o = -pg +endif + obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o obj-$(CONFIG_CEVT_R4K_LIB) += cevt-r4k.o obj-$(CONFIG_MIPS_MT_SMTC) += cevt-smtc.o
@@ -24,6 +29,8 @@ obj-$(CONFIG_SYNC_R4K) += sync-r4k.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o +obj-$(CONFIG_FUNCTION_TRACER) += mcount.o + obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_MIPS64) += r4k_fpu.o r4k_switch.o
arch/mips/kernel/mcount.S new file +98 -0
98 lines not on this page · raw message
arch/mips/kernel/mips_ksyms.c +5 -0
@@ -13,6 +13,7 @@#include <asm/checksum.h> #include <asm/pgtable.h> #include <asm/uaccess.h> +#include <asm/ftrace.h> extern void *__bzero (void *__s,size_t __count); extern long __strncpy_from_user_nocheck_asm(char *__to,
@@ -51,3 +52,7 @@ EXPORT_SYMBOL(csum_partial_copy_nocheck);EXPORT_SYMBOL (__csum_partial_copy_user);EXPORT_SYMBOL (invalid_pte_table); +#ifdef CONFIG_FUNCTION_TRACER +/* _mcount is defined in arch/mips/kernel/mcount.S */ +EXPORT_SYMBOL (_mcount); +#endif
Signature · 1 line
1.6.0.4
PATCH v3 1/1 add an endian argument to scripts/recordmcount.pl
In reply to Wu ZhangjinFrom: Wu Zhangjin <[email protected]>
mips architecture need this argument to handle big/little endian differently.
--- scripts/Makefile.build | 1 + scripts/recordmcount.pl | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-)
scripts/Makefile.build +1 -0
@@ -207,6 +207,7 @@ endif ifdef CONFIG_FTRACE_MCOUNT_RECORD cmd_record_mcount = perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \ + "$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \ "$(if $(CONFIG_64BIT),64,32)" \ "$(OBJDUMP)" "$(OBJCOPY)" "$(CC)" "$(LD)" "$(NM)" "$(RM)" "$(MV)" \ "$(if $(part-of-module),1,0)" "$(@)";
scripts/recordmcount.pl +3 -3
@@ -100,13 +100,13 @@ $P =~ s@.*/@@g; my $V = '0.1'; -if ($#ARGV < 7) { - print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n"; +if ($#ARGV < 8) { + print "usage: $P arch endian bits objdump objcopy cc ld nm rm mv is_module inputfile\n"; print "version: $V\n"; exit(1); } -my ($arch, $bits, $objdump, $objcopy, $cc, +my ($arch, $endian, $bits, $objdump, $objcopy, $cc, $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV; # This file refers to mcount and shouldn't be ftraced, so lets' ignore it
Signature · 1 line
1.6.0.4
PATCH v3 1/1 mips dynamic function tracer support
In reply to Wu ZhangjinFrom: Wu Zhangjin <[email protected]>
dynamic function tracer need to replace "nop" to "jumps & links" and something reversely.
--- arch/mips/Kconfig | 3 + arch/mips/include/asm/ftrace.h | 10 ++ arch/mips/kernel/Makefile | 2 + arch/mips/kernel/ftrace.c | 207 ++++++++++++++++++++++++++++++++++++++++ arch/mips/kernel/mcount.S | 31 ++++++ scripts/recordmcount.pl | 20 ++++ 6 files changed, 273 insertions(+), 0 deletions(-) create mode 100644 arch/mips/kernel/ftrace.c
arch/mips/Kconfig +3 -0
@@ -6,6 +6,9 @@ config MIPS select HAVE_ARCH_KGDB select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_TRACE_MCOUNT_TEST + select HAVE_DYNAMIC_FTRACE + select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE # Horrible source of confusion. Die, die, die ... select EMBEDDED select RTC_LIB
arch/mips/include/asm/ftrace.h +10 -0
@@ -19,6 +19,16 @@extern void _mcount (void );#define mcount _mcount +#ifdef CONFIG_DYNAMIC_FTRACE +/* reloction of mcount call site is the same as the address */ +static inline unsigned long ftrace_call_adjust (unsigned long addr) +{ +return addr; +} + +struct dyn_arch_ftrace { +}; +#endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_TRACER */ #endif /* _ASM_MIPS_FTRACE_H */
arch/mips/kernel/Makefile +2 -0
@@ -10,6 +10,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities +CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_early_printk.o = -pg endif
@@ -30,6 +31,7 @@ obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_MODULES) += mips_ksyms.o module.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o +obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o
arch/mips/kernel/ftrace.c new file +207 -0
207 lines not on this page · raw message
arch/mips/kernel/mcount.S +31 -0
@@ -67,6 +67,35 @@ move ra, $1 .endm +#ifdef CONFIG_DYNAMIC_FTRACE + +LEAF(_mcount) + RESTORE_SP_FOR_32BIT + RETURN_BACK + END(_mcount) + +NESTED(ftrace_caller, PT_SIZE, ra) + RESTORE_SP_FOR_32BIT + lw t0, function_trace_stop + bnez t0, ftrace_stub + nop + + MCOUNT_SAVE_REGS + + MCOUNT_SET_ARGS + .globl ftrace_call +ftrace_call: + jal ftrace_stub + nop + + MCOUNT_RESTORE_REGS + .globl ftrace_stub +ftrace_stub: + RETURN_BACK + END(ftrace_caller) + +#else /* ! CONFIG_DYNAMIC_FTRACE */ + NESTED(_mcount, PT_SIZE, ra) RESTORE_SP_FOR_32BIT PTR_L t0, function_trace_stop
@@ -94,5 +123,7 @@ ftrace_stub: RETURN_BACK END(_mcount) +#endif /* ! CONFIG_DYNAMIC_FTRACE */ + .set at .set reorder
scripts/recordmcount.pl +20 -0
@@ -213,6 +213,26 @@ if ($arch eq "x86_64") { if ($is_module eq "0") { $cc .= " -mconstant-gp"; } + +} elsif ($arch eq "mips") { + $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; + $objdump .= " -Melf-trad".$endian."mips "; + + if ($endian eq "big") { + $endian = " -EB "; + $ld .= " -melf".$bits."btsmip"; + } else { + $endian = " -EL "; + $ld .= " -melf".$bits."ltsmip"; + } + + $cc .= " -mno-abicalls -fno-pic -mabi=" . $bits . $endian; + $ld .= $endian; + + if ($bits == 64) { + $type = ".dword"; + } + } else { die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; }
Signature · 1 line
1.6.0.4
PATCH v3 1/1 filter local function prefixed by $L
In reply to Wu ZhangjinFrom: Wu Zhangjin <[email protected]>
this patch fixed the warning as following:
mipsel-linux-gnu-objcopy: 'fs/proc/.tmp_gl_devices.o': No such file
mipsel-linux-gnu-ld: fs/proc/.tmp_gl_devices.o: No such file: No such file or directory
rm: cannot remove `fs/proc/.tmp_gl_devices.o': No such file or directory
rm: cannot remove `fs/proc/.tmp_mx_devices.o': No such file or directory
the real reason of above warning is that the $Lxx local functions will be treated as global symbols, so, should be filtered.
--- scripts/recordmcount.pl | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
scripts/recordmcount.pl +4 -0
@@ -343,6 +343,10 @@ sub update_funcs if (!$use_locals) { return; } + # filter $LXXX tags + if ("$ref_func" =~ m/\$L/) { + return; + } $convert{$ref_func} = 1; }
Signature · 1 line
1.6.0.4
Re: [PATCH v3] filter local function prefixed by $L
Quoted 23 lines · Wu Zhangjin
From: Wu Zhangjin <[email protected]>
this patch fixed the warning as following:
mipsel-linux-gnu-objcopy: '
fs/proc/.tmp_gl_devices.o': No such file
mipsel-linux-gnu-ld:fs/proc/.tmp_gl_devices.o: No such file: No such file or directory
rm: cannot remove `fs/proc/.tmp_gl_devices.o': No such file or directory
rm: cannot remove `fs/proc/.tmp_mx_devices.o': No such file or directorythe real reason of above warning is that the $Lxx local functions will be treated as global symbols, so, should be filtered.
Signed-off-by Wu Zhangjin <[email protected]>--- scripts/recordmcount.pl | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)scripts/recordmcount.pl +0
-0
scripts/recordmcount.pl sub update_funcs · line 349
Quoted 7 lines
scripts/recordmcount.pl +4
-0@@ -343,6 +343,10 @@ sub update_funcs if (!$use_locals) { return; } + # filter $LXXX tags + if ("$ref_func" =~ m/\$L/) { + return; + }
Certainly this is true for mips. I doubt it is for all architectures targed by Linux.
David Daney
Steven Rostedt
maintainerRe: [PATCH v3] filter local function prefixed by $L
Quoted 19 lines · David Daney
Quoted 18 lines · Wu Zhangjin
From: Wu Zhangjin <[email protected]>
this patch fixed the warning as following:
mipsel-linux-gnu-objcopy: '
fs/proc/.tmp_gl_devices.o': No such file
mipsel-linux-gnu-ld:fs/proc/.tmp_gl_devices.o: No such file: No such file or directory
rm: cannot remove `fs/proc/.tmp_gl_devices.o': No such file or directory
rm: cannot remove `fs/proc/.tmp_mx_devices.o': No such file or directorythe real reason of above warning is that the $Lxx local functions will be treated as global symbols, so, should be filtered.
Signed-off-by Wu Zhangjin <[email protected]>--- scripts/recordmcount.pl | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
Quoted 15 lines
scripts/recordmcount.pl sub update_funcs · line 349
Quoted 12 lines
scripts/recordmcount.pl +4
-0@@ -343,6 +343,10 @@ sub update_funcs if (!$use_locals) { return; } + # filter $LXXX tags + if ("$ref_func" =~ m/\$L/) { + return; + }Certainly this is true for mips. I doubt it is for all architectures targed by Linux.
Yes, that should probably go into a mips only change. Unless you can reproduce it on all other archs, or at least x86.
You could also do this in the function_regex variable.
"^([0-9a-fA-F]+)\\s+<(.|[^\$]L.*?|\$[^L].*?|[^\$][^L].*?)>:"
There may even be a better way, but I'm not in the mood to look it up ;-)
-- Steve
Re: [PATCH v3] filter local function prefixed by $L
Quoted 21 lines · Steven Rostedt
Quoted 19 lines · David Daney
Quoted 18 lines · Wu Zhangjin
From: Wu Zhangjin <[email protected]>
this patch fixed the warning as following:
mipsel-linux-gnu-objcopy: '
fs/proc/.tmp_gl_devices.o': No such file
mipsel-linux-gnu-ld:fs/proc/.tmp_gl_devices.o: No such file: No such file or directory
rm: cannot remove `fs/proc/.tmp_gl_devices.o': No such file or directory
rm: cannot remove `fs/proc/.tmp_mx_devices.o': No such file or directorythe real reason of above warning is that the $Lxx local functions will be treated as global symbols, so, should be filtered.
Signed-off-by Wu Zhangjin <[email protected]>--- scripts/recordmcount.pl | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
Quoted 16 lines
Quoted 7 lines
Quoted 7 lines
scripts/recordmcount.pl +0
-0@@ -343,6 +343,10 @@ sub update_funcs if (!$use_locals) { return;Quoted 8 lines
scripts/recordmcount.pl sub update_funcs · line 349
Quoted 5 lines
scripts/recordmcount.pl +4
-0} + # filter $LXXX tags + if ("$ref_func" =~ m/\$L/) { + return; + }Certainly this is true for mips. I doubt it is for all architectures targed by Linux.
have tried to use function_regex instead, but for I'm poor in playing with regular expression of perl. at last, i use something easier like above. and I _guess_ this problem maybe exist in some other platforms, so just put it there.
Quoted 7 lines
Yes, that should probably go into a mips only change. Unless you can reproduce it on all other archs, or at least x86.
You could also do this in the
function_regexvariable."^([0-9a-fA-F]+)\\s+<(.|[^\$]L.*?|\$[^L].*?|[^\$][^L].*?)>:"
works well, and this seems mips64-specific, so, I moved this specific function_regex to "if ($bits == 64) { ... }".
Quoted 1 line
There may even be a better way, but I'm not in the mood to look it up ;-)
seems not that easy to understand :-)
-- Wu Zhangjin
PATCH v3 1/1 mips function graph tracer support
In reply to Wu ZhangjinFrom: Wu Zhangjin <[email protected]>
this works something like -finstrument-functions does, instead of using
void __cyg_profile_func_enter (void *this_fn,
void *call_site);
void __cyg_profile_func_exit (void *this_fn,
void *call_site);
-pg use _mcount, so some tricks are adoptive by the author of orignal function graph tracer:
the _mcount function will call prepare_function_return to save the parent_ip, ip and calltime in a tracing array, if success, the address of a hooker function &return_to_handler will be substitued to the parent_ip, so, after return from _mcount it will call the &return_to_handler, not back to the parent_ip, but calling ftrace_return_to_handler to remember the rettime, and return the parent_ip to let &return_to_handler go back to the real parent.
--- arch/mips/Kconfig | 1 + arch/mips/kernel/ftrace.c | 66 ++++++++++++++++++++++++++++++++++++++++ arch/mips/kernel/mcount.S | 61 +++++++++++++++++++++++++++++++++++-- arch/mips/kernel/vmlinux.lds.S | 1 + 4 files changed, 126 insertions(+), 3 deletions(-)
arch/mips/Kconfig +1 -0
@@ -9,6 +9,7 @@ config MIPS select HAVE_DYNAMIC_FTRACE select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE + select HAVE_FUNCTION_GRAPH_TRACER # Horrible source of confusion. Die, die, die ... select EMBEDDED select RTC_LIB
arch/mips/kernel/ftrace.c +66 -0
69 lines not on this page · raw message
arch/mips/kernel/mcount.S +58 -3
107 lines not on this page · raw message
arch/mips/kernel/vmlinux.lds.S +1 -0
@@ -36,6 +36,7 @@ SECTIONS SCHED_TEXT LOCK_TEXT KPROBES_TEXT + IRQENTRY_TEXT *(.text.*) *(.fixup) *(.gnu.warning)
Signature · 1 line
1.6.0.4
PATCH v3 1/1 mips specific clock function to get precise timestamp
In reply to Wu ZhangjinFrom: Wu Zhangjin <[email protected]>
by default, trace_clock_local calling sched_clock(jiffies-based) to get timestamp, in x86, there is a tsc(64bit) based sched_clock, but in mips, the 'tsc'(clock counter) is only 32bit long, which will easily rollover, and there is no existing high precise sched_clock in mips, we need to get one ourselves.
to avoid invading the whole linux-mips, i do not want to implement a tsc-based native_sched_clock instead of sched_clock like x86 does. because, there is a need to handling rollover of the only 32-bit long 'tsc' of mips, which will need extra overhead. in reality, i have tried to do it, but made the kernel hangs when booting, I'm not sure why it not work.
so, I just implement a native_sched_clock in arch/mips/kernel/ftrace.c, but not override the original sched_clock(). to get high precise timestamp, we implement a native_trace_clock_local, which will not call original sched_clock again, but native_sched_clock().
and what about the trace_clock and trace_clock_global function, should we also implement a mips-secific one? I'm not sure.
--- arch/mips/kernel/Makefile | 2 + arch/mips/kernel/csrc-r4k.c | 2 +- arch/mips/kernel/ftrace_clock.c | 71 +++++++++++++++++++++++++++++++++++++++ kernel/trace/trace_clock.c | 2 +- 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 arch/mips/kernel/ftrace_clock.c
arch/mips/kernel/Makefile +2 -0
@@ -11,6 +11,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \ ifdef CONFIG_FUNCTION_TRACER # Do not profile debug and lowlevel utilities CFLAGS_REMOVE_ftrace.o = -pg +CFLAGS_REMOVE_ftrace_clock.o = -pg CFLAGS_REMOVE_early_printk.o = -pg endif
@@ -32,6 +33,7 @@ obj-$(CONFIG_MODULES) += mips_ksyms.o module.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o +obj-$(CONFIG_NOP_TRACER) += ftrace_clock.o obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o obj-$(CONFIG_CPU_MIPS32) += r4k_fpu.o r4k_switch.o
arch/mips/kernel/csrc-r4k.c +1 -1
@@ -10,7 +10,7 @@#include <asm/time.h> -static cycle_t c0_hpt_read (struct clocksource *cs) +static cycle_t notrace c0_hpt_read(struct clocksource *cs) {return read_c0_count (); }
arch/mips/kernel/ftrace_clock.c new file +71 -0
71 lines not on this page · raw message
kernel/trace/trace_clock.c +1 -1
@@ -26,7 +26,7 @@* Useful for tracing that does not cross to other CPUs nor * does it go through idle events. */ -u64 notrace trace_clock_local(void) +u64 __attribute__((weak)) notrace trace_clock_local(void) {unsigned long flags;u64 clock;
Signature · 1 line
1.6.0.4
PATCH v3 1/1 mips specific system call tracer
In reply to Wu ZhangjinFrom: Wu Zhangjin <[email protected]>
FIXME: there are several different sys_call_entry in mips64, but currently, i only use the the one in arch/mips/kernel/scall64-o32.S so,if people not use o32 standard, it will not compiled normally.
the system call tracing demo in a debian system on qemu-system-mipsel/malta:
debian-mips-malta:~# mount -t debugfs nodev /debug
debian-mips-malta:~# echo 20000 > /debug/tracing/buffer_size_kb
debian-mips-malta:~# cat /debug/tracing/available_tracers
syscall nop
debian-mips-malta:~# echo syscall > /debug/tracing/current_tracer
debian-mips-malta:~# echo 1 > /debug/tracing/tracing_enabled
debian-mips-malta:~# sleep 1
debian-mips-malta:~# echo 0 > /debug/tracing/tracing_enabled
debian-mips-malta:~# cat /debug/tracing/trace | head -20
<...>-533 [000] 60.458291: sys_write(fd: 1, buf: 4fc408, count: 8)
<...>-533 [000] 64.325614: sys_getrlimit(resource: 3, rlim: 530020)
<...>-533 [000] 64.327089: sys_read(fd: 2, buf: 4fc008, count: 6)
<...>-533 [000] 64.969663: sys_exit(error_code: 2)
<...>-533 [000] 65.608794: sys_exit(error_code: 2)
<...>-533 [000] 66.231796: sys_read(fd: 2, buf: 4fc008, count: 6)
<...>-533 [000] 66.913687: sys_open(filename: 1, flags: 0, mode: a)
<...>-533 [000] 66.914617: sys_exit(error_code: 1)
<...>-533 [000] 70.797507: sys_exit(error_code: 503be8)
<...>-536 [000] 70.833108: sys_exit(error_code: 2aac6cfc)
<...>-536 [000] 70.833897: sys_exit(error_code: 2aac6540)
<...>-536 [000] 70.835711: sys_exit(error_code: 2aac6cfc)
<...>-536 [000] 70.840609: sys_lchown(filename: 3, user: 7fb08b38, group: 20)
<...>-533 [000] 71.877785: sys_open(filename: ffffffff, flags: 7fcf08c8, mode: b)
<...>-533 [000] 75.531122: sys_open(filename: 1, flags: 0, mode: a)--- arch/mips/Kconfig | 1 + arch/mips/include/asm/ptrace.h | 2 + arch/mips/include/asm/reg.h | 5 ++ arch/mips/include/asm/syscall.h | 84 +++++++++++++++++++++++++++++++++++ arch/mips/include/asm/thread_info.h | 5 ++- arch/mips/kernel/Makefile | 1 + arch/mips/kernel/entry.S | 2 +- arch/mips/kernel/ftrace.c | 71 +++++++++++++++++++++++++++++ arch/mips/kernel/ptrace.c | 14 +++++- arch/mips/kernel/scall64-o32.S | 2 +- 10 files changed, 182 insertions(+), 5 deletions(-) create mode 100644 arch/mips/include/asm/syscall.h
arch/mips/Kconfig +1 -0
@@ -10,6 +10,7 @@ config MIPS select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE select HAVE_FUNCTION_GRAPH_TRACER + select HAVE_FTRACE_SYSCALLS # Horrible source of confusion. Die, die, die ... select EMBEDDED select RTC_LIB
arch/mips/include/asm/ptrace.h +2 -0
@@ -45,6 +45,8 @@ struct pt_regs {unsigned long cp0_badvaddr;unsigned long cp0_cause;unsigned long cp0_epc; +/* Used for restarting system calls */ +unsigned long orig_v0;#ifdef CONFIG_MIPS_MT_SMTC unsigned long cp0_tcstatus;#endif /* CONFIG_MIPS_MT_SMTC */
arch/mips/include/asm/reg.h +5 -0
@@ -65,6 +65,8 @@#define EF_CP0_CAUSE 43#define EF_UNUSED0 44 +#define EF_ORIG_V0 45 +#define EF_SIZE 180#endif
@@ -121,6 +123,9 @@#define EF_CP0_STATUS 36#define EF_CP0_CAUSE 37 + +#define EF_ORIG_V0 38 +#define EF_SIZE 304/* size in bytes */ #endif /* CONFIG_64BIT */
arch/mips/include/asm/syscall.h new file +84 -0
84 lines not on this page · raw message
arch/mips/include/asm/thread_info.h +4 -1
@@ -128,6 +128,7 @@ register struct thread_info *__current_thread_info __asm__("$28");#define TIF_32BIT_ADDR 23/* 32-bit address space (o32/n32) */ #define TIF_FPUBOUND 24/* thread bound to FPU-full CPU set */ #define TIF_LOAD_WATCH 25/* If set, load watch registers */ +#define TIF_SYSCALL_FTRACE 27/* for ftrace syscall instrumentation */ #define TIF_SYSCALL_TRACE 31/* syscall trace active */ #ifdef CONFIG_MIPS32_O32
@@ -151,11 +152,13 @@ register struct thread_info *__current_thread_info __asm__("$28");#define _TIF_32BIT_ADDR (1<<TIF_32BIT_ADDR)#define _TIF_FPUBOUND (1<<TIF_FPUBOUND)#define _TIF_LOAD_WATCH (1<<TIF_LOAD_WATCH) +#define _TIF_SYSCALL_FTRACE (1<<TIF_SYSCALL_FTRACE)/* work to do on interrupt/exception return */ #define _TIF_WORK_MASK (0x0000ffef & ~_TIF_SECCOMP)/* work to do on any return to u-space */ -#define _TIF_ALLWORK_MASK (0x8000ffff & ~_TIF_SECCOMP) +#define _TIF_ALLWORK_MASK \ + ((0x8000ffff & ~_TIF_SECCOMP) | _TIF_SYSCALL_FTRACE)#endif /* __KERNEL__ */
arch/mips/kernel/Makefile +1 -0
@@ -33,6 +33,7 @@ obj-$(CONFIG_MODULES) += mips_ksyms.o module.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o +obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o obj-$(CONFIG_NOP_TRACER) += ftrace_clock.o obj-$(CONFIG_CPU_LOONGSON2) += r4k_fpu.o r4k_switch.o
arch/mips/kernel/entry.S +1 -1
@@ -167,7 +167,7 @@ work_notifysig: # deal with pending signals and FEXPORT(syscall_exit_work_partial) SAVE_STATIC syscall_exit_work: - li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_FTRACE and t0, a2 # a2 is preloaded with TI_FLAGS beqz t0, work_pending # trace bit set? local_irq_enable # could let do_syscall_trace()
arch/mips/kernel/ftrace.c +71 -0
80 lines not on this page · raw message
arch/mips/kernel/ptrace.c +12 -2
@@ -25,6 +25,7 @@#include <linux/security.h> #include <linux/audit.h> #include <linux/seccomp.h> +#include <linux/ftrace.h> #include <asm/byteorder.h> #include <asm/cpu.h>
@@ -39,6 +40,7 @@#include <asm/bootinfo.h> #include <asm/reg.h> +#include <trace/syscall.h> /* * Called by kernel/ptrace.c when detaching.. *
@@ -60,7 +62,7 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data)struct pt_regs *regs;int i; -if (!access_ok (VERIFY_WRITE , data,38 *8 )) +if (!access_ok (VERIFY_WRITE , data,39 *8 ))return -EIO ; regs =task_pt_regs (child);
@@ -73,6 +75,7 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data)__put_user ((long )regs->cp0_badvaddr, data +EF_CP0_BADVADDR -EF_R0 );__put_user ((long )regs->cp0_status, data +EF_CP0_STATUS -EF_R0 );__put_user ((long )regs->cp0_cause, data +EF_CP0_CAUSE -EF_R0 ); +__put_user ((long )regs->orig_v0, data +EF_ORIG_V0 -EF_R0 );return 0 ; }
@@ -87,7 +90,7 @@ int ptrace_setregs(struct task_struct *child, __s64 __user *data)struct pt_regs *regs;int i; -if (!access_ok (VERIFY_READ , data,38 *8 )) +if (!access_ok (VERIFY_READ , data,39 *8 ))return -EIO ; regs =task_pt_regs (child);
@@ -97,6 +100,7 @@ int ptrace_setregs(struct task_struct *child, __s64 __user *data)__get_user (regs->lo, data +EF_LO -EF_R0 );__get_user (regs->hi, data +EF_HI -EF_R0 );__get_user (regs->cp0_epc, data +EF_CP0_EPC -EF_R0 ); +__get_user (regs->orig_v0, data +EF_ORIG_V0 -EF_R0 );/* badvaddr, status, and cause may not be written. */
@@ -575,6 +579,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)if (!(current->ptrace &PT_PTRACED )) goto out; +if (unlikely (test_thread_flag (TIF_SYSCALL_FTRACE ))) +ftrace_syscall_exit (regs); +if (!test_thread_flag (TIF_SYSCALL_TRACE )) goto out;
@@ -594,6 +601,9 @@ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) } out: +if (unlikely (test_thread_flag (TIF_SYSCALL_FTRACE ))) +ftrace_syscall_enter (regs); +if (unlikely (current->audit_context) && !entryexit) audit_syscall_entry(audit_arch(), regs->regs[0], regs->regs[4], regs->regs[5],
arch/mips/kernel/scall64-o32.S +1 -1
@@ -202,7 +202,7 @@ einval: li v0, -ENOSYS .align 3 .type sys_call_table,@object -sys_call_table: +EXPORT(sys_call_table) PTR sys32_syscall /* 4000 */ PTR sys_exit PTR sys_fork
Signature · 1 line
1.6.0.4