From mboxrd@z Thu Jan 1 00:00:00 1970 Received: with ECARTIS (v1.0.0; list linux-mips); Mon, 13 Aug 2012 17:44:56 +0200 (CEST) Received: from mail-gg0-f177.google.com ([209.85.161.177]:64877 "EHLO mail-gg0-f177.google.com" rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP id S1903677Ab2HMPop (ORCPT ); Mon, 13 Aug 2012 17:44:45 +0200 Received: by ggnm2 with SMTP id m2so3486770ggn.36 for ; Mon, 13 Aug 2012 08:44:39 -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=jvFy4qkwLTBPlXHNUTs3JKoq/KAxqCelquhCifIVVs4=; b=Wbm/g6AewlYfOdINXXzoZoOs0wrKEdQ6zYBfmVW599n3r5UtG9rfVl/U96gfGlPT0l 9fmITEvzDoI5a0JhPRRg7+cqPAMXCd1tFgMSrjmnqHFEx5hjUt0B6RppspuPieZRdINW yyWCAwK+S/wJa/AeAPD4PCM9t+Sf9+NKSVgl+dOBDWzVj4K1EVePnFCAtZWCot9Ayjkf NHQUsG0WP2Vas8L+jqzvSNXETSf+cnOuu1t1cAKh+nuKBpWqqEuWUHGbC6WwhdMGLpI7 fnq2eoqqP0vYqS3X1t4wJVszFdDDCkeU8AR4zNmO6vyjgA5HBK51YOZc3XO3IZHYYIoy OT3w== MIME-Version: 1.0 Received: by 10.68.219.135 with SMTP id po7mr18901841pbc.149.1344872678937; Mon, 13 Aug 2012 08:44:38 -0700 (PDT) Received: by 10.67.14.106 with HTTP; Mon, 13 Aug 2012 08:44:38 -0700 (PDT) In-Reply-To: References: Date: Mon, 13 Aug 2012 21:14:38 +0530 Message-ID: Subject: Re: [Bug-fix] backtrace when HAVE_FUNCTION_TRACER is enable From: Akhilesh Kumar To: ralf@linux-mips.org, Wu Zhangjin Cc: linux-mips@linux-mips.org Content-Type: multipart/alternative; boundary=e89a8ff248194bd31804c72792c3 X-archive-position: 34128 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: X-Status: A --e89a8ff248194bd31804c72792c3 Content-Type: text/plain; charset=ISO-8859-1 Hi Ralf/John, Detail Description is added in the patch Thanks, Akhilesh >>From 89004f88a1f8399be7a856b43b475f06c3d5bb30 Mon Sep 17 00:00:00 2001 From: Akhilesh Kumar Date: Fri, 4 May 2012 18:52:46 +0530 Subject: process_backtrace Patch fix the backtrcae problem using unwind_stack()) When ftrace is used, unwind_stack() is unable to retrieve the frame info and call-trace doesn't work. test module ---------------- static struct timer_list backtrace_timer; static void backtrace_test_timer(unsigned long data) { printk("Testing a backtrace from irq context.\n"); printk("The following trace is a kernel self test and not a bug!\n"); dump_stack(); } static int backtrace_regression_test(void) { printk("====[ backtrace testing ]===========\n"); printk("Testing a backtrace from process context.\n"); printk("The following trace is a kernel self test and not a bug!\n"); dump_stack(); init_timer(&backtrace_timer); backtrace_timer.function = backtrace_test_timer; mod_timer(&backtrace_timer, jiffies + 10); msleep(10); printk("====[ end of backtrace testing ]====\n"); return 0; } static void exitf(void) { } module_init(backtrace_regression_test); module_exit(exitf); MODULE_LICENSE("GPL"); --------------------------------------------------------------------- out put when HAVE_FUNCTION_TRACER is disable ====[ 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 --------------------------------------------------------------------- VDLinux#> insmod sisc_backtrcae.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; @@ -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 10:46 PM, Akhilesh Kumar wrote: > 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; >> > > --e89a8ff248194bd31804c72792c3 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
Hi Ralf/John,

Detail=A0Description is ad= ded in the patch=A0

Thanks,
Akhilesh =A0=
=A0
=A0


From 89004f88= a1f8399be7a856b43b475f06c3d5bb30 Mon Sep 17 00:00:00 2001
From: =A0Akhilesh Kumar <akhilesh.lxr@...com>
Date: Fr= i, 4 May 2012 18:52:46 +0530
Subject: process_backtrace Patch fix= the backtrcae =A0problem using unwind_stack())

Wh= en ftrace is used, unwind_stack() is unable to retrieve the frame info
and call-trace doesn't work.

test module<= /div>
----------------
static struct timer_list backtrace_tim= er;
static void backtrace_test_timer(unsigned long data)
{
printk("Testing a backtrace from irq context.\n"= );
printk("The following trace is a kernel self test and not= a
bug!\n");
dump_stack();
}
static int backtrace_regression_test(void)
{
printk(&qu= ot;=3D=3D=3D=3D[ backtrace testing ]=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n&quo= t;);
printk("Testing a backtrace from process context.\n&quo= t;);
printk("The following trace is a kernel self test and n= ot a
bug!\n");
dump_stack();

init_t= imer(&backtrace_timer);
backtrace_timer.function =3D backtrac= e_test_timer;
mod_timer(&backtrace_timer, jiffies + 10);

msleep(10);
printk("=3D=3D=3D=3D[ end of= backtrace testing ]=3D=3D=3D=3D\n");
return 0;
}<= /div>
static void exitf(void)
{
}
module_= init(backtrace_regression_test);
module_exit(exitf);
MODULE_LICENSE("GPL");
---------------------------------------------------------------------
out put when HAVE_FUNCTION_TRACER is disable

=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 tr= ace 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
[<800609= 54>] sys_init_module+0x19c8/0x1c60
[<8000a418>] stack_done+0x20/0x40

outpu= t befor patch when HAVE_FUNCTION_TRACER is enable
---------------= ------------------------------------------------------
VDLinux#&g= t; insmod sisc_backtrcae.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 tr= ace 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 ba= cktrace testing ]=3D=3D=3D=3D
-----------------------------------= -------------------
above shows the wrong back trcae

output after= patch when HAVE_FUNCTION_TRACER is enable
----------------------= ------------------------------------------------
=3D=3D=3D=3D[ ba= cktrace testing ]=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Testing a backtrace from process context.
The following trac= e 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
[&l= t;c003405c>] backtrace_test_timer+0x5c/0x74 [sisc_backtrcae]
[= <c00340dc>] init_module+0x68/0xa0 [sisc_backtrcae]
[<800= 00508>] do_one_initcall+0x108/0x1f0
[<8006d4c4>] sys_init_module+0x1a10/0x1c74
[<8000b0= 38>] 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 findi= ng the save_lr instruction, it returns.
It doesn't handle the= ftrace condition.

If Dynamic Frace "CONFIG_DYNAMIC_FTRACE" is e= nabled, the instrumentation
code is:
- jal <ftrace_c= aller>
- addiu sp,sp,-8
Thus, the current Frame Size= of function is increased by 8 for Ftrace.

Signed-off-by: Akhilesh Kumar <akhilesh.lxr@...com&g= t;
---
arch/mips/kernel/process.c | =A0 67
++= ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 67 in= sertions(+), 0 deletions(-)

diff --git a/arch/mips/kernel/process.c b/arch/mips/ker= nel/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 =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(addr) =A0\
+ =A0 =A0 =A0((unsigned int)(JA= L | (((addr) >> 2) & ADDR_MASK)))
+
+/*
=
+ * We assume jal <mcount>/<ftrace_caller> to be present i= n
+ * first JAL_MAX_OFFSET instructions.
+ * Increment this, i= f its otherwise
+ */
+#define JAL_MAX_OFFSET 16U
<= div>+#define MCOUNT_STACK_INST 0x27bdfff8 /* addiu =A0 sp,sp,-8 */
+
+/*
+ * If Dynamic Ftrace is enabled, ftrace_caller i= s the trace function.
+ * Otherwise its - mcount
+ */
+extern void =A0ftrace_caller(void);
+#endif /* CONFIG_D= YNAMIC_FTRACE */
+
static int get_frame_info(struct mips_frame_info *info)
{
union mips_instruction *ip =3D info->func;
unsigned max_insns =3D info->func_size / sizeof(union mips_instruction)= ;
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
+
info-&= gt;pc_offset =3D -1;
info->frame_size =3D 0;

@@ -306,6 +339,28 @@ static int get_frame_info(struct mips_frame_in= fo *info)
max_insns =3D 128U; /* unknown function size */
max_insns = =3D min(128U, max_insns);

+#ifdef CONFIG_DYNAMIC_F= TRACE
+ max_prolog_inst =3D min(JAL_MAX_OFFSET, max_prolog_inst);=
+ jal_mcount =3D INSN_JAL((unsigned)&ftrace_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 MCOUNT_S= TACK_INST))
+ =A0 =A0 ) {
+ =A0 jal_found =3D 1;
+ =A0 break;
+ =A0}
+ }
+ /* restore the ip to start of function */
+ ip= =3D info->func;
+#endif
+
for (i =3D 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
+ /*
+ =A0* to offset the effect of:
+ =A0* addiu = =A0 sp,sp,-8
+ =A0*/
+ if (jal_found) {
+ =A0= if (info->frame_size)
+ =A0 info->frame_size +=3D 8;
<= div>+ =A0if (info->pc_offset >=3D 0)
+ =A0 info->pc_offset +=3D 8 / sizeof(long);
+ }
+#endif
if (info->frame_size && info->pc_offset &= gt;=3D 0) /* nested */
return 0;
if (info->pc_offset= < 0) /* leaf */
--
1.7.8.4








=
On Thu, Aug 9, 2012 at 10:46 PM, Akhilesh Kumar = <akhilesh.lxr@gmail.com> wrote:
yes Zhangin

please find t= he=A0complete=A0patch=A0
=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 i= nt 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;


--e89a8ff248194bd31804c72792c3-- From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-gg0-f177.google.com ([209.85.161.177]:64877 "EHLO mail-gg0-f177.google.com" rhost-flags-OK-OK-OK-OK) by eddie.linux-mips.org with ESMTP id S1903677Ab2HMPop (ORCPT ); Mon, 13 Aug 2012 17:44:45 +0200 MIME-Version: 1.0 In-Reply-To: References: Date: Mon, 13 Aug 2012 21:14:38 +0530 Message-ID: Subject: Re: [Bug-fix] backtrace when HAVE_FUNCTION_TRACER is enable From: Akhilesh Kumar Content-Type: multipart/alternative; boundary=e89a8ff248194bd31804c72792c3 Sender: linux-mips-bounce@linux-mips.org Errors-to: linux-mips-bounce@linux-mips.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-subscribe: List-owner: List-post: List-archive: Return-Path: To: ralf@linux-mips.org, Wu Zhangjin Cc: linux-mips@linux-mips.org Message-ID: <20120813154438.IDqDVPaAUtg94nW4rZfKMcleUZpELOSAxFJKeVKa8oc@z> --e89a8ff248194bd31804c72792c3 Content-Type: text/plain; charset=ISO-8859-1 Hi Ralf/John, Detail Description is added in the patch Thanks, Akhilesh >From 89004f88a1f8399be7a856b43b475f06c3d5bb30 Mon Sep 17 00:00:00 2001 From: Akhilesh Kumar Date: Fri, 4 May 2012 18:52:46 +0530 Subject: process_backtrace Patch fix the backtrcae problem using unwind_stack()) When ftrace is used, unwind_stack() is unable to retrieve the frame info and call-trace doesn't work. test module ---------------- static struct timer_list backtrace_timer; static void backtrace_test_timer(unsigned long data) { printk("Testing a backtrace from irq context.\n"); printk("The following trace is a kernel self test and not a bug!\n"); dump_stack(); } static int backtrace_regression_test(void) { printk("====[ backtrace testing ]===========\n"); printk("Testing a backtrace from process context.\n"); printk("The following trace is a kernel self test and not a bug!\n"); dump_stack(); init_timer(&backtrace_timer); backtrace_timer.function = backtrace_test_timer; mod_timer(&backtrace_timer, jiffies + 10); msleep(10); printk("====[ end of backtrace testing ]====\n"); return 0; } static void exitf(void) { } module_init(backtrace_regression_test); module_exit(exitf); MODULE_LICENSE("GPL"); --------------------------------------------------------------------- out put when HAVE_FUNCTION_TRACER is disable ====[ 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 --------------------------------------------------------------------- VDLinux#> insmod sisc_backtrcae.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; @@ -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 10:46 PM, Akhilesh Kumar wrote: > 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; >> > > --e89a8ff248194bd31804c72792c3 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
Hi Ralf/John,

Detail=A0Description is ad= ded in the patch=A0

Thanks,
Akhilesh =A0=
=A0
=A0


From 89004f88= a1f8399be7a856b43b475f06c3d5bb30 Mon Sep 17 00:00:00 2001
From: =A0Akhilesh Kumar <akhilesh.lxr@...com>
Date: Fr= i, 4 May 2012 18:52:46 +0530
Subject: process_backtrace Patch fix= the backtrcae =A0problem using unwind_stack())

Wh= en ftrace is used, unwind_stack() is unable to retrieve the frame info
and call-trace doesn't work.

test module<= /div>
----------------
static struct timer_list backtrace_tim= er;
static void backtrace_test_timer(unsigned long data)
{
printk("Testing a backtrace from irq context.\n"= );
printk("The following trace is a kernel self test and not= a
bug!\n");
dump_stack();
}
static int backtrace_regression_test(void)
{
printk(&qu= ot;=3D=3D=3D=3D[ backtrace testing ]=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n&quo= t;);
printk("Testing a backtrace from process context.\n&quo= t;);
printk("The following trace is a kernel self test and n= ot a
bug!\n");
dump_stack();

init_t= imer(&backtrace_timer);
backtrace_timer.function =3D backtrac= e_test_timer;
mod_timer(&backtrace_timer, jiffies + 10);

msleep(10);
printk("=3D=3D=3D=3D[ end of= backtrace testing ]=3D=3D=3D=3D\n");
return 0;
}<= /div>
static void exitf(void)
{
}
module_= init(backtrace_regression_test);
module_exit(exitf);
MODULE_LICENSE("GPL");
---------------------------------------------------------------------
out put when HAVE_FUNCTION_TRACER is disable

=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 tr= ace 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
[<800609= 54>] sys_init_module+0x19c8/0x1c60
[<8000a418>] stack_done+0x20/0x40

outpu= t befor patch when HAVE_FUNCTION_TRACER is enable
---------------= ------------------------------------------------------
VDLinux#&g= t; insmod sisc_backtrcae.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 tr= ace 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 ba= cktrace testing ]=3D=3D=3D=3D
-----------------------------------= -------------------
above shows the wrong back trcae

output after= patch when HAVE_FUNCTION_TRACER is enable
----------------------= ------------------------------------------------
=3D=3D=3D=3D[ ba= cktrace testing ]=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Testing a backtrace from process context.
The following trac= e 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
[&l= t;c003405c>] backtrace_test_timer+0x5c/0x74 [sisc_backtrcae]
[= <c00340dc>] init_module+0x68/0xa0 [sisc_backtrcae]
[<800= 00508>] do_one_initcall+0x108/0x1f0
[<8006d4c4>] sys_init_module+0x1a10/0x1c74
[<8000b0= 38>] 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 findi= ng the save_lr instruction, it returns.
It doesn't handle the= ftrace condition.

If Dynamic Frace "CONFIG_DYNAMIC_FTRACE" is e= nabled, the instrumentation
code is:
- jal <ftrace_c= aller>
- addiu sp,sp,-8
Thus, the current Frame Size= of function is increased by 8 for Ftrace.

Signed-off-by: Akhilesh Kumar <akhilesh.lxr@...com&g= t;
---
arch/mips/kernel/process.c | =A0 67
++= ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 67 in= sertions(+), 0 deletions(-)

diff --git a/arch/mips/kernel/process.c b/arch/mips/ker= nel/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 =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(addr) =A0\
+ =A0 =A0 =A0((unsigned int)(JA= L | (((addr) >> 2) & ADDR_MASK)))
+
+/*
=
+ * We assume jal <mcount>/<ftrace_caller> to be present i= n
+ * first JAL_MAX_OFFSET instructions.
+ * Increment this, i= f its otherwise
+ */
+#define JAL_MAX_OFFSET 16U
<= div>+#define MCOUNT_STACK_INST 0x27bdfff8 /* addiu =A0 sp,sp,-8 */
+
+/*
+ * If Dynamic Ftrace is enabled, ftrace_caller i= s the trace function.
+ * Otherwise its - mcount
+ */
+extern void =A0ftrace_caller(void);
+#endif /* CONFIG_D= YNAMIC_FTRACE */
+
static int get_frame_info(struct mips_frame_info *info)
{
union mips_instruction *ip =3D info->func;
unsigned max_insns =3D info->func_size / sizeof(union mips_instruction)= ;
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
+
info-&= gt;pc_offset =3D -1;
info->frame_size =3D 0;

@@ -306,6 +339,28 @@ static int get_frame_info(struct mips_frame_in= fo *info)
max_insns =3D 128U; /* unknown function size */
max_insns = =3D min(128U, max_insns);

+#ifdef CONFIG_DYNAMIC_F= TRACE
+ max_prolog_inst =3D min(JAL_MAX_OFFSET, max_prolog_inst);=
+ jal_mcount =3D INSN_JAL((unsigned)&ftrace_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 MCOUNT_S= TACK_INST))
+ =A0 =A0 ) {
+ =A0 jal_found =3D 1;
+ =A0 break;
+ =A0}
+ }
+ /* restore the ip to start of function */
+ ip= =3D info->func;
+#endif
+
for (i =3D 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
+ /*
+ =A0* to offset the effect of:
+ =A0* addiu = =A0 sp,sp,-8
+ =A0*/
+ if (jal_found) {
+ =A0= if (info->frame_size)
+ =A0 info->frame_size +=3D 8;
<= div>+ =A0if (info->pc_offset >=3D 0)
+ =A0 info->pc_offset +=3D 8 / sizeof(long);
+ }
+#endif
if (info->frame_size && info->pc_offset &= gt;=3D 0) /* nested */
return 0;
if (info->pc_offset= < 0) /* leaf */
--
1.7.8.4








=
On Thu, Aug 9, 2012 at 10:46 PM, Akhilesh Kumar = <akhilesh.lxr@gmail.com> wrote:
yes Zhangin

please find t= he=A0complete=A0patch=A0
=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 i= nt 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;


--e89a8ff248194bd31804c72792c3--