21 Sep, 2011

1 commit

  • arch/mips/kernel/ftrace.c: In function ‘ftrace_get_parent_ra_addr’:
    arch/mips/kernel/ftrace.c:212: error: implicit declaration of function ‘in_kernel_space’
    arch/mips/kernel/ftrace.c: In function ‘prepare_ftrace_return’:
    arch/mips/kernel/ftrace.c:314: error: ‘MCOUNT_OFFSET_INSNS’ undeclared (first use in this function)
    arch/mips/kernel/ftrace.c:314: error: (Each undeclared identifier is reported only once
    arch/mips/kernel/ftrace.c:314: error: for each function it appears in.)

    Signed-off-by: Thomas Gleixner
    To: linux-mips@linux-mips.org
    Patchwork: https://patchwork.linux-mips.org/patch/2634/
    Signed-off-by: Ralf Baechle

    Thomas Gleixner
     

11 May, 2011

1 commit

  • The current code is abusing the uasm interface by passing jump target
    addresses with high bits set. Mask the addresses to avoid annoying
    messages at boot time.

    Signed-off-by: David Daney
    Cc: Steven Rostedt
    Cc: Wu Zhangjin
    Patchwork: https://patchwork.linux-mips.org/patch/1922/
    Signed-off-by: Ralf Baechle

    David Daney
     

15 Mar, 2011

5 commits

  • trace.func should be set to the recorded ip of the mcount calling site
    in the __mcount_loc section to filter the function entries configured
    through the tracing/set_graph_function interface, but before, this is
    set to the self_ra(the return address of mcount), which has made
    set_graph_function not work as expected.

    This fixes it via calculating the right recorded ip in the __mcount_loc
    section and assign it to trace.func.

    Reported-by: Zhiping Zhong
    Signed-off-by: Wu Zhangjin
    Cc: Steven Rostedt
    Cc: Sergei Shtylyov
    Cc: linux-mips@linux-mips.org
    Patchwork: https://patchwork.linux-mips.org/patch/2017/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • This moves the comments out of ftrace_make_nop() and cleans it. At the
    same time, a macro MCOUNT_OFFSET_INSNS is defined for sharing with the
    next patch.

    Signed-off-by: Wu Zhangjin
    Cc: Steven Rostedt
    Cc: linux-mips@linux-mips.org
    Patchwork: https://patchwork.linux-mips.org/patch/2008/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • The old prepare_ftrace_return() for MIPS is confused and have introduced
    some problem. This patch cleans up the names of the arguments, variables
    and related functions.

    For MIPS, the 2nd argument of prepare_ftrace_return() is not really the
    'selfpc' described in ftrace-design.txt but instead it is the self
    return address. This did break the compatibility of the generic
    interface but really reduced one unneeded calculation for to get the
    current function name, the parent return address and the self return
    address are enough, no need to tranform the self return address to the
    self address.

    But set_graph_function of function graph tracer is an exception, it does
    need the 2nd argument of prepare_ftrace_return() as 'selfpc', for it
    will use 'selfpc' to match user's configuration of function graph
    entries, but in reality, it doesn't need the 'selfpc' but the recorded
    ip address of the mcount calling site in the __mcount_loc section. So,
    the 2nd argument of prepare_ftrace_return() is not important, the real
    requirement is the right recorded ip address should be calculated and
    assign to trace.func, this will be fixed in the next patches.

    Reported-by: Zhiping Zhong
    Signed-off-by: Wu Zhangjin
    Cc: Steven Rostedt
    Cc: linux-mips@linux-mips.org
    Patchwork: https://patchwork.linux-mips.org/patch/2007/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • The old in_module() may not work in some situations(e.g. when module &
    kernel are in the same address space when CONFIG_MAPPED_KERNEL=y), The
    in_kernel_space() is more generic and it is also easy to be implemented
    via cloning the existing core_kernel_text(), so, replace the in_module()
    with in_kernel_space().

    Signed-off-by: Wu Zhangjin
    Cc: Steven Rostedt
    Cc: linux-mips@linux-mips.org
    Patchwork: https://patchwork.linux-mips.org/patch/2005/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • This simply moves the "ip-=4" statement down to the end of the do { ...
    } while (...); loop, which reduces one unneeded subtration and the
    subsequent memory loading and comparison.

    Signed-off-by: Wu Zhangjin
    Cc: Steven Rostedt
    Cc: linux-mips@linux-mips.org
    Patchwork: https://patchwork.linux-mips.org/patch/2006/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     

06 Jul, 2010

5 commits

  • This patch adds an inline function in_module() to check which space the
    instruction pointer in, kernel space or module space.

    Note: This will not work when the kernel space and module space are the
    same. If they are the same, we need to modify scripts/recordmcount.pl,
    ftrace_make_nop/call() and the other related parts to ensure the
    enabling/disabling of the calling site to _mcount is right for both
    kernel and module.

    [Ralf: It also is still incorrect for some 64-bit kernels.]

    Signed-off-by: Wu Zhangjin
    Cc: linux-mips
    Cc: David Daney
    Patchwork: http://patchwork.linux-mips.org/patch/1232/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • Cleans up comments and ftrace_get_parent_addr() of function graph tracer.

    Signed-off-by: Wu Zhangjin
    Cc: linux-mips
    Cc: David Daney
    Patchwork: http://patchwork.linux-mips.org/patch/1231/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • With the help of uasm this patch encodes the instructions of the dynamic
    function tracer in ftrace_dyn_arch_init() when initializing it.

    As a result we can remove the dynamic encoding of instructions in
    ftrace_make_nop()/call(), ftrace_enable_ftrace_graph_caller() and remove
    the macro jump_insn_encode() and at last this reduce the overhead of
    dynamic Function Tracer. This also is cleaner.

    Signed-off-by: Wu Zhangjin
    Cc: linux-mips
    Cc: David Daney
    Patchwork: http://patchwork.linux-mips.org/patch/1230/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • This patch adds some cleanups of the instructions:
    o use macros instead of magic numbers
    o use macros instead of variables to reduce some overhead
    o add new macro for the jal instruction

    Signed-off-by: Wu Zhangjin
    Cc: linux-mips
    Cc: David Daney
    Patchwork: http://patchwork.linux-mips.org/patch/1229/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • For 32-bit kernel the -mmcount-ra-address option of gcc 4.5 emits one
    extra instruction before calling to _mcount so we need to use a different
    "b 1f" for it.

    Signed-off-by: Wu Zhangjin
    Cc: linux-mips
    Cc: David Daney
    Patchwork: http://patchwork.linux-mips.org/patch/1228/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     

27 Feb, 2010

1 commit


17 Dec, 2009

5 commits

  • That thread "MIPS: Add option to pass return address location to
    _mcount" from "David Daney " have added a new
    option -mmcount-ra-address to gcc(4.5) for MIPS to transfer the location
    of the return address to _mcount.

    Benefit from this new feature, function graph tracer on MIPS will be
    easier and safer to hijack the return address of the kernel function,
    which will save some overhead and make the whole thing more reliable.

    In this patch, at first, try to enable the option -mmcount-ra-address in
    arch/mips/Makefile with cc-option, if gcc support it, it will be
    enabled, otherwise, no side effect.

    and then, we need to support this new option of gcc 4.5 and also support
    the old gcc versions.

    with _mcount in the old gcc versions, it's not easy to get the location
    of return address(tracing: add function graph tracer support for MIPS),
    so, we do it in a C function: ftrace_get_parent_addr(ftrace.c), but
    with -mmcount-ra-address, only several instructions need to get what
    we want, so, I put into asm(mcount.S). and also, as the $12(t0) is
    used by -mmcount-ra-address for transferring the localtion of return
    address to _mcount, we need to save it into the stack and restore it
    when enabled dynamic function tracer, 'Cause we have called
    "ftrace_call" before "ftrace_graph_caller", which may destroy
    $12(t0).

    (Thanks to David for providing that -mcount-ra-address and giving the
    idea of KBUILD_MCOUNT_RA_ADDRESS, both of them have made the whole
    thing more beautiful!)

    Signed-off-by: Wu Zhangjin
    Cc: Steven Rostedt
    Cc: Nicholas Mc Guire
    Cc: zhangfx@lemote.com
    Cc: Wu Zhangjin
    Cc: Ingo Molnar
    Cc: Thomas Gleixner
    Cc: Frederic Weisbecker
    Cc: linux-kernel@vger.kernel.org
    Cc: linux-mips@linux-mips.org
    Patchwork: http://patchwork.linux-mips.org/patch/681/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • When remove the -fno-omit-frame-pointer, gcc will not save the frame
    pointer for us, we need to save one ourselves.

    Signed-off-by: Wu Zhangjin
    Cc: Steven Rostedt
    Cc: Nicholas Mc Guire
    Cc: zhangfx@lemote.com
    Cc: Wu Zhangjin
    Cc: Ingo Molnar
    Cc: Thomas Gleixner
    Cc: Frederic Weisbecker
    Cc: linux-kernel@vger.kernel.org
    Cc: linux-mips@linux-mips.org
    Patchwork: http://patchwork.linux-mips.org/patch/679/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • This patch make function graph tracer work with dynamic function tracer.

    To share the source code of dynamic function tracer(MCOUNT_SAVE_REGS),
    and avoid restoring the whole saved registers, we need to restore the ra
    register from the stack.

    (NOTE: This not work with 32bit! need to ensure why!)

    Signed-off-by: Wu Zhangjin
    Cc: Steven Rostedt
    Cc: Nicholas Mc Guire
    Cc: zhangfx@lemote.com
    Cc: Wu Zhangjin
    Cc: Ingo Molnar
    Cc: Thomas Gleixner
    Cc: Frederic Weisbecker
    Cc: linux-kernel@vger.kernel.org
    Cc: linux-mips@linux-mips.org
    Patchwork: http://patchwork.linux-mips.org/patch/678/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • The implementation of function graph tracer for MIPS is a little
    different from X86.

    in MIPS, gcc(with -pg) only transfer the caller's return address(at) and
    the _mcount's return address(ra) to us.

    For the kernel part without -mlong-calls:

    move at, ra
    jal _mcount

    For the module part with -mlong-calls:

    lui v1, hi16bit_of_mcount
    addiu v1, v1, low16bit_of_mcount
    move at, ra
    jal _mcount

    Without -mlong-calls,

    if the function is a leaf, it will not save the return address(ra):

    ffffffff80101298 :
    ffffffff80101298: 67bdfff0 daddiu sp,sp,-16
    ffffffff8010129c: ffbe0008 sd s8,8(sp)
    ffffffff801012a0: 03a0f02d move s8,sp
    ffffffff801012a4: 03e0082d move at,ra
    ffffffff801012a8: 0c042930 jal ffffffff8010a4c0
    ffffffff801012ac: 00020021 nop

    so, we can hijack it directly in _mcount, but if the function is non-leaf, the
    return address is saved in the stack.

    ffffffff80133030 :
    ffffffff80133030: 67bdff50 daddiu sp,sp,-176
    ffffffff80133034: ffbe00a0 sd s8,160(sp)
    ffffffff80133038: 03a0f02d move s8,sp
    ffffffff8013303c: ffbf00a8 sd ra,168(sp)
    ffffffff80133040: ffb70098 sd s7,152(sp)
    ffffffff80133044: ffb60090 sd s6,144(sp)
    ffffffff80133048: ffb50088 sd s5,136(sp)
    ffffffff8013304c: ffb40080 sd s4,128(sp)
    ffffffff80133050: ffb30078 sd s3,120(sp)
    ffffffff80133054: ffb20070 sd s2,112(sp)
    ffffffff80133058: ffb10068 sd s1,104(sp)
    ffffffff8013305c: ffb00060 sd s0,96(sp)
    ffffffff80133060: 03e0082d move at,ra
    ffffffff80133064: 0c042930 jal ffffffff8010a4c0
    ffffffff80133068: 00020021 nop

    but we can not get the exact stack address(which saved ra) directly in
    _mcount, we need to search the content of at register in the stack space
    or search the "s{d,w} ra, offset(sp)" instruction in the text. 'Cause we
    can not prove there is only a match in the stack space, so, we search
    the text instead.

    as we can see, if the first instruction above "move at, ra" is not a
    store instruction, there should be a leaf function, so we hijack the at
    register directly via putting &return_to_handler into it, otherwise, we
    search the "s{d,w} ra, offset(sp)" instruction to get the stack offset,
    and then the stack address. we use the above copy_process() as an
    example, we at last find "ffbf00a8", 0xa8 is the stack offset, we plus
    it with s8(fp), that is the stack address, we hijack the content via
    writing the &return_to_handler in.

    If with -mlong-calls, since there are two more instructions above "move
    at, ra", so, we can move the pointer to the position above "lui v1,
    hi16bit_of_mcount".

    Signed-off-by: Wu Zhangjin
    Cc: Steven Rostedt
    Cc: Nicholas Mc Guire
    Cc: zhangfx@lemote.com
    Cc: Wu Zhangjin
    Cc: Ingo Molnar
    Cc: Thomas Gleixner
    Cc: Frederic Weisbecker
    Cc: linux-kernel@vger.kernel.org
    Cc: linux-mips@linux-mips.org
    Patchwork: http://patchwork.linux-mips.org/patch/677/
    Signed-off-by: Ralf Baechle

    Wu Zhangjin
     
  • With dynamic function tracer, by default, _mcount is defined as an
    "empty" function, it returns directly without any more action . When
    enabling it in user-space, it will jump to a real tracing
    function(ftrace_caller), and do the real job for us.

    Differ from the static function tracer, dynamic function tracer provides
    two functions ftrace_make_call()/ftrace_make_nop() to enable/disable the
    tracing of some indicated kernel functions(set_ftrace_filter).

    In the -v4 version, the implementation of this support is basically the same as
    X86 version does: _mcount is implemented as an empty function and ftrace_caller
    is implemented as a real tracing function respectively.

    But in this version, to support module tracing with the help of
    -mlong-calls in arch/mips/Makefile:

    MODFLAGS += -mlong-calls.

    The stuff becomes a little more complex. We need to cope with two
    different type of calling to _mcount.

    For the kernel part, the calling to _mcount(result of "objdump -hdr
    vmlinux"). is like this:

    108: 03e0082d move at,ra
    10c: 0c000000 jal 0
    10c: R_MIPS_26 _mcount
    10c: R_MIPS_NONE *ABS*
    10c: R_MIPS_NONE *ABS*
    110: 00020021 nop

    For the module with -mlong-calls, it looks like this:

    c: 3c030000 lui v1,0x0
    c: R_MIPS_HI16 _mcount
    c: R_MIPS_NONE *ABS*
    c: R_MIPS_NONE *ABS*
    10: 64630000 daddiu v1,v1,0
    10: R_MIPS_LO16 _mcount
    10: R_MIPS_NONE *ABS*
    10: R_MIPS_NONE *ABS*
    14: 03e0082d move at,ra
    18: 0060f809 jalr v1

    In the kernel version, there is only one "_mcount" string for every
    kernel function, so, we just need to match this one in mcount_regex of
    scripts/recordmcount.pl, but in the module version, we need to choose
    one of the two to match. Herein, I choose the first one with
    "R_MIPS_HI16 _mcount".

    and In the kernel verion, without module tracing support, we just need
    to replace "jal _mcount" by "jal ftrace_caller" to do real tracing, and
    filter the tracing of some kernel functions via replacing it by a nop
    instruction.

    but as we have described before, the instruction "jal ftrace_caller" only left
    32bit length for the address of ftrace_caller, it will fail when calling from
    the module space. so, herein, we must replace something else.

    the basic idea is loading the address of ftrace_caller to v1 via changing these
    two instructions:

    lui v1,0x0
    addiu v1,v1,0

    If we want to enable the tracing, we need to replace the above instructions to:

    lui v1, HI_16BIT_ftrace_caller
    addiu v1, v1, LOW_16BIT_ftrace_caller

    If we want to stop the tracing of the indicated kernel functions, we
    just need to replace the "jalr v1" to a nop instruction. but we need to
    replace two instructions and encode the above two instructions
    oursevles.

    Is there a simpler solution? Yes! Here it is, in this version, we put _mcount
    and ftrace_caller together, which means the address of _mcount and
    ftrace_caller is the same:

    _mcount:
    ftrace_caller:
    j ftrace_stub
    nop

    ...(do real tracing here)...

    ftrace_stub:
    jr ra
    move ra, at

    By default, the kernel functions call _mcount, and then jump to ftrace_stub and
    return. and when we want to do real tracing, we just need to remove that "j
    ftrace_stub", and it will run through the two "nop" instructions and then do
    the real tracing job.

    what about filtering job? we just need to do this:

    lui v1, hi_16bit_of_mcount b 1f (0x10000004)
    addiu v1, v1, low_16bit_of_mcount
    move at, ra
    jalr v1
    nop
    1f: (rec->ip + 12)

    In linux-mips64, there will be some local symbols, whose name are
    prefixed by $L, which need to be filtered. thanks goes to Steven for
    writing the mips64-specific function_regex.

    In a conclusion, with RISC, things becomes easier with such a "stupid"
    trick, RISC is something like K.I.S.S, and also, there are lots of
    "simple" tricks in the whole ftrace support, thanks goes to Steven and
    the other folks for providing such a wonderful tracing framework!

    Signed-off-by: Wu Zhangjin
    Cc: Nicholas Mc Guire
    Cc: zhangfx@lemote.com
    Cc: Wu Zhangjin
    Cc: Ingo Molnar
    Cc: Thomas Gleixner
    Cc: Frederic Weisbecker
    Cc: linux-kernel@vger.kernel.org
    Cc: linux-mips@linux-mips.org
    Patchwork: http://patchwork.linux-mips.org/patch/675/
    Acked-by: Steven Rostedt
    Signed-off-by: Ralf Baechle

    Wu Zhangjin