From mboxrd@z Thu Jan 1 00:00:00 1970 Received: with ECARTIS (v1.0.0; list linux-mips); Thu, 09 Aug 2012 19:17:13 +0200 (CEST) Received: from mail-pb0-f49.google.com ([209.85.160.49]:52314 "EHLO mail-pb0-f49.google.com" rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP id S1902233Ab2HIRRE (ORCPT ); Thu, 9 Aug 2012 19:17:04 +0200 Received: by pbbrq13 with SMTP id rq13so1315638pbb.36 for ; Thu, 09 Aug 2012 10:16:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=/UxgkjcBimowHD03erl1dsewBThdVXdUC4C4LRlJ0tM=; b=IgrS8EexrHbS8UUWvfxwNu2b0pVfH1IUNbApQgZPmAPs5k7F0YI8tINiZ8UoGNRnyX Sxdd6PyBhoTkrV01V9bG1lX9myOCxPn3DxAR6evnV1p9gc2lccxxGCA0dj+t6P2n9H3V L2OjMGtG9p8J10w1+LFsJgmn6lKVTQ2hJRCRcZ/rsAND/fBo72/svaomvX4oA1BbtTvd ZiJ+GRXl6dmp8waH+DN+4CJTSgCMhcPJwN8NT7c4fw5CyGopZw3pbcJo+mQ80b9Wt3Nu N/KTSeu1HJId92vDBVmkMYzy9HVmyRWoDxdoKiA1g2N9z9PDiFV1f1uLBQVhh8yzWzd9 xVyQ== MIME-Version: 1.0 Received: by 10.68.217.226 with SMTP id pb2mr5537868pbc.105.1344532617320; Thu, 09 Aug 2012 10:16:57 -0700 (PDT) Received: by 10.67.14.106 with HTTP; Thu, 9 Aug 2012 10:16:57 -0700 (PDT) In-Reply-To: References: Date: Thu, 9 Aug 2012 22:46:57 +0530 Message-ID: Subject: Re: [Bug-fix] backtrace when HAVE_FUNCTION_TRACER is enable From: Akhilesh Kumar To: wuzhangjin@gmail.com, ralf@linux-mips.org Cc: linux-mips@linux-mips.org Content-Type: multipart/alternative; boundary=e89a8ff243250b582004c6d865e8 X-archive-position: 34085 X-ecartis-version: Ecartis v1.0.0 Sender: linux-mips-bounce@linux-mips.org Errors-to: linux-mips-bounce@linux-mips.org X-original-sender: akhilesh.lxr@gmail.com Precedence: bulk List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: linux-mips X-List-ID: linux-mips List-subscribe: List-owner: List-post: List-archive: X-list: linux-mips Return-Path: --e89a8ff243250b582004c6d865e8 Content-Type: text/plain; charset=ISO-8859-1 yes Zhangin please find the complete patch ==================================================================== diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 7955409..df72738 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -290,12 +290,45 @@ static inline int is_sp_move_ins(union mips_instruction *ip) return 0; } +#ifdef CONFIG_DYNAMIC_FTRACE +/* + * To create the jal <> instruction from mcount. + * taken from: + * - arch/mips/kernel/ftrace.c + */ +#define ADDR_MASK 0x03ffffff /* op_code|addr : 31...26|25 ....0 */ +#define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */ +#define INSN_JAL(addr) \ + ((unsigned int)(JAL | (((addr) >> 2) & ADDR_MASK))) + +/* + * We assume jal / to be present in + * first JAL_MAX_OFFSET instructions. + * Increment this, if its otherwise + */ +#define JAL_MAX_OFFSET 16U +#define MCOUNT_STACK_INST 0x27bdfff8 /* addiu sp,sp,-8 */ + +/* + * If Dynamic Ftrace is enabled, ftrace_caller is the trace function. + * Otherwise its - mcount + */ +extern void ftrace_caller(void); +#endif /* CONFIG_DYNAMIC_FTRACE */ + static int get_frame_info(struct mips_frame_info *info) { union mips_instruction *ip = info->func; unsigned max_insns = info->func_size / sizeof(union mips_instruction); unsigned i; +#ifdef CONFIG_DYNAMIC_FTRACE + unsigned max_prolog_inst = max_insns; + int jal_found = 0; + /* instruction corresponding to jal <_mcount>/ */ + int jal_mcount = 0; +#endif + info->pc_offset = -1; info->frame_size = 0; @@ -306,6 +339,28 @@ static int get_frame_info(struct mips_frame_info *info) max_insns = 128U; /* unknown function size */ max_insns = min(128U, max_insns); +#ifdef CONFIG_DYNAMIC_FTRACE + max_prolog_inst = min(JAL_MAX_OFFSET, max_prolog_inst); + jal_mcount = INSN_JAL((unsigned)&ftrace_caller); + + for (i = 0; i < max_prolog_inst; i++, ip++) { + if ((*(int *)ip == jal_mcount) || + /* + * for dyn ftrace, the code initially has 0. + * so we check whether the next instruction is + * addiu sp,sp,-8 + */ + (!(*(int *)ip) && + (*(int *)(ip + 1) == MCOUNT_STACK_INST)) + ) { + jal_found = 1; + break; + } + } + /* restore the ip to start of function */ + ip = info->func; +#endif + for (i = 0; i < max_insns; i++, ip++) { if (is_jal_jalr_jr_ins(ip)) @@ -321,6 +376,18 @@ static int get_frame_info(struct mips_frame_info *info) break; } } +#ifdef CONFIG_DYNAMIC_FTRACE + /* + * to offset the effect of: + * addiu sp,sp,-8 + */ + if (jal_found) { + if (info->frame_size) + info->frame_size += 8; + if (info->pc_offset >= 0) + info->pc_offset += 8 / sizeof(long); + } +#endif if (info->frame_size && info->pc_offset >= 0) /* nested */ return 0; if (info->pc_offset < 0) /* leaf */ -- 1.7.8.4 ==================================================================== On Thu, Aug 9, 2012 at 9:41 PM, Wu Zhangjin wrote: > Hi, Akhilesh > > Thanks very much for your work. > > Seems this patch has lost something, can you send a full one? > > Best Regards, > Wu Zhangjin > > On Thu, Aug 9, 2012 at 9:53 PM, Akhilesh Kumar > wrote: > > Hi Ralf, > > > > > > Sub:- Bug unable to retrive backtrace when HAVE_FUNCTION_TRACER is > enable. > > I send this bug and bug fix long back, I am resending this patch again > for > > review. > > > > Please review below patch if you agree I will regenerate this patch and > with > > you. > > > > ====[ backtrace testing ]=========== > > Testing a backtrace from process context. > > The following trace is a kernel self test and not a bug! > > Testing a backtrace. > > The following trace is a kernel self test and not a bug! > > Call Trace: > > [<80295134>] dump_stack+0x8/0x34 > > [] backtrace_regression_test+0x60/0x94 [sisc_backtrcae] > > [<800004f0>] do_one_initcall+0xf0/0x1d0 > > [<80060954>] sys_init_module+0x19c8/0x1c60 > > [<8000a418>] stack_done+0x20/0x40 > > output befor patch when HAVE_FUNCTION_TRACER is enable > > --------------------------------------------------------------------- > > #> insmod backtrace.ko > > ====[ backtrace testing ]=========== > > Testing a backtrace from process context. > > The following trace is a kernel self test and not a bug! > > Testing a backtrace. > > The following trace is a kernel self test and not a bug! > > Call Trace: > > [<802e5164>] dump_stack+0x1c/0x50 > > [<802e5164>] dump_stack+0x1c/0x50 > > ====[ end of backtrace testing ]==== > > ------------------------------------------------------ > > above shows the wrong back trcae > > output after patch when HAVE_FUNCTION_TRACER is enable > > ---------------------------------------------------------------------- > > ====[ backtrace testing ]=========== > > Testing a backtrace from process context. > > The following trace is a kernel self test and not a bug! > > Testing a backtrace. > > The following trace is a kernel self test and not a bug! > > Call Trace: > > [<802eb1a4>] dump_stack+0x20/0x54 > > [] backtrace_test_timer+0x5c/0x74 [sisc_backtrcae] > > [] init_module+0x68/0xa0 [sisc_backtrcae] > > [<80000508>] do_one_initcall+0x108/0x1f0 > > [<8006d4c4>] sys_init_module+0x1a10/0x1c74 > > [<8000b038>] stack_done+0x20/0x40 > > ------------------------------------------------------------------ > > get_frame_info() is used to fetch the frame information from the > > function. > > However, > > 1. this function just considers the first stack adjustment for frame > > size. > > 2. On finding the save_lr instruction, it returns. > > It doesn't handle the ftrace condition. > > If Dynamic Frace "CONFIG_DYNAMIC_FTRACE" is enabled, the instrumentation > > code is: > > - jal > > - addiu sp,sp,-8 > > Thus, the current Frame Size of function is increased by 8 for Ftrace. > > Signed-off-by: Akhilesh Kumar > > --- > > arch/mips/kernel/process.c | 67 > > ++++++++++++++++++++++++++++++++++++++++++++ > > 1 files changed, 67 insertions(+), 0 deletions(-) > > diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c > > index 7955409..df72738 100644 > > --- a/arch/mips/kernel/process.c > > +++ b/arch/mips/kernel/process.c > > @@ -290,12 +290,45 @@ static inline int is_sp_move_ins(union > > mips_instruction *ip) > > return 0; > > } > > +#ifdef CONFIG_DYNAMIC_FTRACE > > +/* > > + * To create the jal <> instruction from mcount. > > + * taken from: > > + * - arch/mips/kernel/ftrace.c > > + */ > > +#define ADDR_MASK 0x03ffffff /* op_code|addr : 31...26|25 ....0 */ > > +#define JAL 0x0c000000 /* jump & link: ip --> ra, jump to target */ > > +#define INSN_JAL(addr) \ > > + ((unsigned int)(JAL | (((addr) >> 2) & ADDR_MASK))) > > + > > +/* > > + * We assume jal / to be present in > > + * first JAL_MAX_OFFSET instructions. > > + * Increment this, if its otherwise > > + */ > > +#define JAL_MAX_OFFSET 16U > > +#define MCOUNT_STACK_INST 0x27bdfff8 /* addiu sp,sp,-8 */ > > + > > +/* > > + * If Dynamic Ftrace is enabled, ftrace_caller is the trace function. > > + * Otherwise its - mcount > > + */ > > +extern void ftrace_caller(void); > > +#endif /* CONFIG_DYNAMIC_FTRACE */ > > + > > static int get_frame_info(struct mips_frame_info *info) > > { > > union mips_instruction *ip = info->func; > > unsigned max_insns = info->func_size / sizeof(union mips_instruction); > > unsigned i; > > +#ifdef CONFIG_DYNAMIC_FTRACE > > + unsigned max_prolog_inst = max_insns; > > + int jal_found = 0; > > + /* instruction corresponding to jal <_mcount>/ */ > > + int jal_mcount = 0; > > +#endif > > + > > info->pc_offset = -1; > > info->frame_size = 0; > --e89a8ff243250b582004c6d865e8 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable yes Zhangin

please find the=A0complete=A0patch=A0
<= div>=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index 7955409..df72738 100644
--- a/arch/mips/kernel/process= .c
+++ b/arch/mips/kernel/process.c
@@ -290,12 +290,45 = @@ static inline int is_sp_move_ins(union
mips_instruction *ip)
=A0 return 0;
=A0}

+#ifdef CONFIG_D= YNAMIC_FTRACE
+/*
+ * To create the jal <> instru= ction from mcount.
+ * taken from:
+ * - arch/mips/kern= el/ftrace.c
+ */
+#define ADDR_MASK 0x03ffffff =A0 =A0/* =A0op_code|addr= : 31...26|25 ....0 */
+#define JAL 0x0c000000 =A0 =A0 =A0/* jump= & link: ip --> ra, jump to target */
+#define INSN_JAL(ad= dr) =A0\
+ =A0 =A0 =A0((unsigned int)(JAL | (((addr) >> 2) & ADDR_MAS= K)))
+
+/*
+ * We assume jal <mcount>/&= lt;ftrace_caller> to be present in
+ * first JAL_MAX_OFFSET in= structions.
+ * Increment this, if its otherwise
+ */
+#define= JAL_MAX_OFFSET 16U
+#define MCOUNT_STACK_INST 0x27bdfff8 /* addi= u =A0 sp,sp,-8 */
+
+/*
+ * If Dynamic Ftrace= is enabled, ftrace_caller is the trace function.
+ * Otherwise its - mcount
+ */
+extern void =A0ft= race_caller(void);
+#endif /* CONFIG_DYNAMIC_FTRACE */
= +
=A0static int get_frame_info(struct mips_frame_info *info)
=A0{
=A0 union mips_instruction *ip =3D info->func;
=
=A0 unsigned max_insns =3D info->func_size / sizeof(union mips_inst= ruction);
=A0 unsigned i;

+#ifdef CONFIG= _DYNAMIC_FTRACE
+ unsigned max_prolog_inst =3D max_insns;
+ int jal_found = =3D 0;
+ /* instruction corresponding to jal <_mcount>/<= ftrace_caller> */
+ int jal_mcount =3D 0;
+#endif
+
=A0 info->pc_offset =3D -1;
=A0 info->frame_siz= e =3D 0;

@@ -306,6 +339,28 @@ static int get_frame= _info(struct mips_frame_info *info)
=A0 =A0max_insns =3D 128U; /*= unknown function size */
=A0 max_insns =3D min(128U, max_insns);

+#ifd= ef CONFIG_DYNAMIC_FTRACE
+ max_prolog_inst =3D min(JAL_MAX_OFFSET= , max_prolog_inst);
+ jal_mcount =3D INSN_JAL((unsigned)&ftra= ce_caller);
+
+ for (i =3D 0; i < max_prolog_inst; i++, ip++) {
=
+ =A0if ((*(int *)ip =3D=3D jal_mcount) ||
+ =A0 =A0/*
=
+ =A0 =A0 * for dyn ftrace, the code initially has 0.
+ =A0 = =A0 * so we check whether the next instruction is
+ =A0 =A0 * addiu =A0 sp,sp,-8
+ =A0 =A0 */
+ =A0 = =A0(!(*(int *)ip) &&
+ =A0 =A0 (*(int *)(ip + 1) =3D=3D M= COUNT_STACK_INST))
+ =A0 =A0 ) {
+ =A0 jal_found =3D 1;=
+ =A0 break;
+ =A0}
+ }
+ /* restore the ip to start of functio= n */
+ ip =3D info->func;
+#endif
+
<= div>=A0 for (i =3D 0; i < max_insns; i++, ip++) {

=A0 =A0if (is_jal_jalr_jr_ins(ip))
@@ -321,6 +376,18 @@ static int get_frame_info(struct mips_frame_info = *info)
=A0 =A0 break;
=A0 =A0}
=A0 }
+#ifdef CONFIG_DYNAMIC_FTRACE
+ /*
+ =A0* to offset t= he effect of:
+ =A0* addiu =A0 sp,sp,-8
+ =A0*/
+ if (jal_found)= {
+ =A0if (info->frame_size)
+ =A0 info->frame_s= ize +=3D 8;
+ =A0if (info->pc_offset >=3D 0)
+ = =A0 info->pc_offset +=3D 8 / sizeof(long);
+ }
+#endif
=A0 if (info->frame_size &&= info->pc_offset >=3D 0) /* nested */
=A0 =A0return 0;
=A0 if (info->pc_offset < 0) /* leaf */
--=A0
1.7.8.4

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=A0

On Thu, Aug 9, 2012 at 9:41 PM,= Wu Zhangjin <wuzhangjin@gmail.com> wrote:
Hi, Akhilesh

Thanks very much for your work.

Seems this patch has lost something, can you send a full one?

Best Regards,
Wu Zhangjin

On Thu, Aug 9, 2012 at 9:53 PM, Akhilesh Kumar <akhilesh.lxr@gmail.com> wrote:
> Hi Ralf,
>
>
> Sub:- Bug =A0unable to retrive backtrace when HAVE_FUNCTION_TRACER is = enable.
> I send this bug and bug fix long back, I am resending this patch again= for
> review.
>
> Please review below patch if you agree I will regenerate this patch an= d with
> you.
>
> =3D=3D=3D=3D[ backtrace testing ]=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> Testing a backtrace from process context.
> The following trace is a kernel self test and not a bug!
> Testing a backtrace.
> The following trace is a kernel self test and not a bug!
> Call Trace:
> [<80295134>] dump_stack+0x8/0x34
> [<c0946060>] backtrace_regression_test+0x60/0x94 [sisc_backtrcae= ]
> [<800004f0>] do_one_initcall+0xf0/0x1d0
> [<80060954>] sys_init_module+0x19c8/0x1c60
> [<8000a418>] stack_done+0x20/0x40
> output befor patch when HAVE_FUNCTION_TRACER is enable
> ---------------------------------------------------------------------<= br> > #> insmod backtrace.ko
> =3D=3D=3D=3D[ backtrace testing ]=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> Testing a backtrace from process context.
> The following trace is a kernel self test and not a bug!
> Testing a backtrace.
> The following trace is a kernel self test and not a bug!
> Call Trace:
> [<802e5164>] dump_stack+0x1c/0x50
> [<802e5164>] dump_stack+0x1c/0x50
> =3D=3D=3D=3D[ end of backtrace testing ]=3D=3D=3D=3D
> ------------------------------------------------------
> above shows the wrong back trcae
> output after patch when HAVE_FUNCTION_TRACER is enable
> ----------------------------------------------------------------------=
> =3D=3D=3D=3D[ backtrace testing ]=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
> Testing a backtrace from process context.
> The following trace is a kernel self test and not a bug!
> Testing a backtrace.
> The following trace is a kernel self test and not a bug!
> Call Trace:
> [<802eb1a4>] dump_stack+0x20/0x54
> [<c003405c>] backtrace_test_timer+0x5c/0x74 [sisc_backtrcae]
> [<c00340dc>] init_module+0x68/0xa0 [sisc_backtrcae]
> [<80000508>] do_one_initcall+0x108/0x1f0
> [<8006d4c4>] sys_init_module+0x1a10/0x1c74
> [<8000b038>] stack_done+0x20/0x40
> ------------------------------------------------------------------
> get_frame_info() is used to fetch the frame information from the
> function.
> However,
> 1. this function just considers the first stack adjustment for frame > size.
> 2. On finding the save_lr instruction, it returns.
> It doesn't handle the ftrace condition.
> If Dynamic Frace "CONFIG_DYNAMIC_FTRACE" is enabled, the ins= trumentation
> code is:
> =A0- jal <ftrace_caller>
> =A0- addiu sp,sp,-8
> Thus, the current Frame Size of function is increased by 8 for Ftrace.=
> Signed-off-by: Akhilesh Kumar <akhilesh.lxr@gmail.com>
> ---
> =A0arch/mips/kernel/process.c | =A0 67
> ++++++++++++++++++++++++++++++++++++++++++++
> =A01 files changed, 67 insertions(+), 0 deletions(-)
> diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c > index 7955409..df72738 100644
> --- a/arch/mips/kernel/process.c
> +++ b/arch/mips/kernel/process.c
> @@ -290,12 +290,45 @@ =A0static inline int is_sp_move_ins(union
> mips_instruction *ip)
> =A0 return 0;
> =A0}
> +#ifdef CONFIG_DYNAMIC_FTRACE
> +/*
> + * To create the jal <> instruction from mcount.
> + * taken from:
> + * - arch/mips/kernel/ftrace.c
> + */
> +#define ADDR_MASK 0x03ffffff =A0 =A0/* =A0op_code|addr : 31...26|25 .= ...0 */
> +#define JAL 0x0c000000 =A0 =A0 =A0/* jump & link: ip --> ra, j= ump to target */
> +#define INSN_JAL(addr) =A0\
> + =A0 =A0 =A0((unsigned int)(JAL | (((addr) >> 2) & ADDR_MAS= K)))
> +
> +/*
> + * We assume jal <mcount>/<ftrace_caller> to be present i= n
> + * first JAL_MAX_OFFSET instructions.
> + * Increment this, if its otherwise
> + */
> +#define JAL_MAX_OFFSET 16U
> +#define MCOUNT_STACK_INST 0x27bdfff8 /* addiu =A0 sp,sp,-8 */
> +
> +/*
> + * If Dynamic Ftrace is enabled, ftrace_caller is the trace function.=
> + * Otherwise its - mcount
> + */
> +extern void =A0ftrace_caller(void);
> +#endif /* CONFIG_DYNAMIC_FTRACE */
> +
> =A0static int get_frame_info(struct mips_frame_info *info)
> =A0{
> =A0 union mips_instruction *ip =3D info->func;
> =A0 unsigned max_insns =3D info->func_size / sizeof(union mips_inst= ruction);
> =A0 unsigned i;
> +#ifdef CONFIG_DYNAMIC_FTRACE
> + unsigned max_prolog_inst =3D max_insns;
> + int jal_found =3D 0;
> + /* instruction corresponding to jal <_mcount>/<ftrace_calle= r> */
> + int jal_mcount =3D 0;
> +#endif
> +
> =A0 info->pc_offset =3D -1;
> =A0 info->frame_size =3D 0;

--e89a8ff243250b582004c6d865e8--