Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932640AbeAOGtP (ORCPT + 1 other); Mon, 15 Jan 2018 01:49:15 -0500 Received: from mail-pl0-f67.google.com ([209.85.160.67]:45170 "EHLO mail-pl0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932136AbeAOGsP (ORCPT ); Mon, 15 Jan 2018 01:48:15 -0500 X-Google-Smtp-Source: ACJfBosA3KBDDOzQDspquf7v7jcQbBbmW9tLlnhvfBx7C8MYSKOrwOJpiJtHDEeFSzGpjHVv15QVlA== From: Alan Kao X-Google-Original-From: Alan Kao To: Palmer Dabbelt , Albert Ou , Christoph Hellwig , Steven Rostedt , Ingo Molnar , Masahiro Yamada , Kamil Rytarowski , Andrew Morton , patches@groups.riscv.org, linux-kernel@vger.kernel.org Cc: Alan Kao , Greentime Hu Subject: [PATCH v2 3/6] riscv/ftrace: Add dynamic function graph tracer support Date: Mon, 15 Jan 2018 14:47:39 +0800 Message-Id: <20180115064742.25324-4-alankao@andestech.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180115064742.25324-1-alankao@andestech.com> References: <20180115064742.25324-1-alankao@andestech.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: Once the function_graph tracer is enabled, a filtered function has the following call sequence: * ftracer_caller ==> on/off by ftrace_make_call/ftrace_make_nop * ftrace_graph_caller * ftrace_graph_call ==> on/off by ftrace_en/disable_ftrace_graph_caller * prepare_ftrace_return Considering the following DYNAMIC_FTRACE_WITH_REGS feature, it would be more extendable to have a ftrace_graph_caller function, instead of calling prepare_ftrace_return directly in ftrace_caller. Cc: Greentime Hu Signed-off-by: Alan Kao --- arch/riscv/kernel/ftrace.c | 25 +++++++++++++++- arch/riscv/kernel/mcount-dyn.S | 65 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/arch/riscv/kernel/ftrace.c b/arch/riscv/kernel/ftrace.c index 311c287433c9..dce1286af9b0 100644 --- a/arch/riscv/kernel/ftrace.c +++ b/arch/riscv/kernel/ftrace.c @@ -51,7 +51,7 @@ static int __ftrace_modify_call(unsigned long hook_pos, unsigned long target, unsigned int nops[2] = {NOP4, NOP4}; int ret = 0; - /* when ftrace_make_nop is called */ + /* for ftrace_make_nop and ftrace_disable_ftrace_graph_caller */ if (!enable) ret = ftrace_check_current_call(hook_pos, calls); @@ -105,6 +105,7 @@ int __init ftrace_dyn_arch_init(void) } #endif +#ifdef CONFIG_FUNCTION_GRAPH_TRACER /* * Most of this function is copied from arm64. */ @@ -137,3 +138,25 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, return; *parent = return_hooker; } + +#ifdef CONFIG_DYNAMIC_FTRACE +extern void ftrace_graph_call(void); +int ftrace_enable_ftrace_graph_caller(void) +{ + int ret = ftrace_check_current_call((unsigned long)&ftrace_graph_call, + NULL); + + if (ret) + return ret; + + return __ftrace_modify_call((unsigned long)&ftrace_graph_call, + (unsigned long)&prepare_ftrace_return, true); +} + +int ftrace_disable_ftrace_graph_caller(void) +{ + return __ftrace_modify_call((unsigned long)&ftrace_graph_call, + (unsigned long)&prepare_ftrace_return, false); +} +#endif /* CONFIG_DYNAMIC_FTRACE */ +#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ diff --git a/arch/riscv/kernel/mcount-dyn.S b/arch/riscv/kernel/mcount-dyn.S index 57f80fe09cbd..64e715d4e180 100644 --- a/arch/riscv/kernel/mcount-dyn.S +++ b/arch/riscv/kernel/mcount-dyn.S @@ -14,18 +14,63 @@ .text .macro SAVE_ABI_STATE +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + addi sp, sp, -48 + sd s0, 32(sp) + sd ra, 40(sp) + addi s0, sp, 48 + sd t0, 24(sp) + sd t1, 16(sp) +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST + sd t2, 8(sp) +#endif +#else addi sp, sp, -16 sd s0, 0(sp) sd ra, 8(sp) addi s0, sp, 16 +#endif .endm .macro RESTORE_ABI_STATE +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + ld s0, 32(sp) + ld ra, 40(sp) + addi sp, sp, 48 +#else ld ra, 8(sp) ld s0, 0(sp) addi sp, sp, 16 +#endif .endm + .macro RESTORE_GRAPH_ARGS + ld a0, 24(sp) + ld a1, 16(sp) +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST + ld a2, 8(sp) +#endif + .endm + +ENTRY(ftrace_graph_caller) + addi sp, sp, -16 + sd s0, 0(sp) + sd ra, 8(sp) + addi s0, sp, 16 +ftrace_graph_call: + .global ftrace_graph_call + /* + * Calling ftrace_enable/disable_ftrace_graph_caller would overwrite the + * nops below. Check ftrace_modify_all_code for details. + */ + addi x0, x0, 0 + addi x0, x0, 0 + ld ra, 8(sp) + ld s0, 0(sp) + addi sp, sp, 16 + ret +ENDPROC(ftrace_graph_caller) + ENTRY(ftrace_caller) /* * a0: the address in the caller when calling ftrace_caller @@ -33,6 +78,20 @@ ENTRY(ftrace_caller) */ ld a1, -8(s0) addi a0, ra, -MCOUNT_INSN_SIZE + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + /* + * the graph tracer (specifically, prepare_ftrace_return) needs these + * arguments but for now the function tracer occupies the regs, so we + * save them in temporary regs to recover later. + */ + addi t0, s0, -8 + mv t1, a0 +#ifdef HAVE_FUNCTION_GRAPH_FP_TEST + ld t2, -16(s0) +#endif +#endif + SAVE_ABI_STATE ftrace_call: .global ftrace_call @@ -47,6 +106,12 @@ ftrace_call: */ addi x0, x0, 0 addi x0, x0, 0 + +#ifdef CONFIG_FUNCTION_GRAPH_TRACER + RESTORE_GRAPH_ARGS + call ftrace_graph_caller +#endif + RESTORE_ABI_STATE ret ENDPROC(ftrace_caller) -- 2.15.1