All of lore.kernel.org
 help / color / mirror / Atom feed
* [Bug-fix] backtrace when HAVE_FUNCTION_TRACER is enable
@ 2012-08-09 13:53 Akhilesh Kumar
       [not found] ` <CAD+V5YKZJHKONehvT+-GrKLP2+e0PiLiFTJWEojiDoNyLT3yGQ@mail.gmail.com>
  0 siblings, 1 reply; 7+ messages in thread
From: Akhilesh Kumar @ 2012-08-09 13:53 UTC (permalink / raw)
  To: ralf; +Cc: linux-mips

[-- Attachment #1: Type: text/plain, Size: 4060 bytes --]

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
[<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
---------------------------------------------------------------------
#> 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
[<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 instrumentation
code is:
 - jal <ftrace_caller>
 - 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>
---
 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 <mcount>/<ftrace_caller> 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>/<ftrace_caller> */
+ int jal_mcount = 0;
+#endif
+
  info->pc_offset = -1;
  info->frame_size = 0;

[-- Attachment #2: Type: text/html, Size: 4927 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Bug-fix] backtrace when HAVE_FUNCTION_TRACER is enable
       [not found] ` <CAD+V5YKZJHKONehvT+-GrKLP2+e0PiLiFTJWEojiDoNyLT3yGQ@mail.gmail.com>
@ 2012-08-09 17:16   ` Akhilesh Kumar
  2012-08-12  6:28     ` John Crispin
  2012-08-13 15:44       ` Akhilesh Kumar
  0 siblings, 2 replies; 7+ messages in thread
From: Akhilesh Kumar @ 2012-08-09 17:16 UTC (permalink / raw)
  To: wuzhangjin, ralf; +Cc: linux-mips

[-- Attachment #1: Type: text/plain, Size: 7764 bytes --]

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 <mcount>/<ftrace_caller> 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>/<ftrace_caller> */
+ 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 <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  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
> > [<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
> > ---------------------------------------------------------------------
> > #> 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
> > [<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 instrumentation
> > code is:
> >  - jal <ftrace_caller>
> >  - 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>
> > ---
> >  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 <mcount>/<ftrace_caller> 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>/<ftrace_caller> */
> > + int jal_mcount = 0;
> > +#endif
> > +
> >   info->pc_offset = -1;
> >   info->frame_size = 0;
>

[-- Attachment #2: Type: text/html, Size: 10288 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Bug-fix] backtrace when HAVE_FUNCTION_TRACER is enable
  2012-08-09 17:16   ` Akhilesh Kumar
@ 2012-08-12  6:28     ` John Crispin
  2012-08-13 15:44       ` Akhilesh Kumar
  1 sibling, 0 replies; 7+ messages in thread
From: John Crispin @ 2012-08-12  6:28 UTC (permalink / raw)
  To: linux-mips

Hi,

This patch is missing the Description and SoB line

John



On 09/08/12 19:16, 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 <mcount>/<ftrace_caller> 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>/<ftrace_caller> */
> + 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 <wuzhangjin@gmail.com
> <mailto: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 <mailto:akhilesh.lxr@gmail.com>> 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
>     > [<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
>     > ---------------------------------------------------------------------
>     > #> 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
>     > [<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
>     instrumentation
>     > code is:
>     >  - jal <ftrace_caller>
>     >  - 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
>     <mailto:akhilesh.lxr@gmail.com>>
>     > ---
>     >  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 <mcount>/<ftrace_caller> 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>/<ftrace_caller> */
>     > + int jal_mcount = 0;
>     > +#endif
>     > +
>     >   info->pc_offset = -1;
>     >   info->frame_size = 0;
> 
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Bug-fix] backtrace when HAVE_FUNCTION_TRACER is enable
@ 2012-08-13 15:44       ` Akhilesh Kumar
  0 siblings, 0 replies; 7+ messages in thread
From: Akhilesh Kumar @ 2012-08-13 15:44 UTC (permalink / raw)
  To: ralf, Wu Zhangjin; +Cc: linux-mips

[-- Attachment #1: Type: text/plain, Size: 14588 bytes --]

Hi Ralf/John,

Detail Description is added in the patch

Thanks,
Akhilesh




>From 89004f88a1f8399be7a856b43b475f06c3d5bb30 Mon Sep 17 00:00:00 2001
From:  Akhilesh Kumar <akhilesh.lxr@...com>
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
[<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
---------------------------------------------------------------------
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
[<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 instrumentation
code is:
- jal <ftrace_caller>
- 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>
---
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 <mcount>/<ftrace_caller> 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>/<ftrace_caller> */
+ 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 <akhilesh.lxr@gmail.com>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 <mcount>/<ftrace_caller> 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>/<ftrace_caller> */
> + 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 <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  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
>> > [<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
>> > ---------------------------------------------------------------------
>> > #> 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
>> > [<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 instrumentation
>> > code is:
>> >  - jal <ftrace_caller>
>> >  - 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>
>> > ---
>> >  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 <mcount>/<ftrace_caller> 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>/<ftrace_caller> */
>> > + int jal_mcount = 0;
>> > +#endif
>> > +
>> >   info->pc_offset = -1;
>> >   info->frame_size = 0;
>>
>
>

[-- Attachment #2: Type: text/html, Size: 20031 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Bug-fix] backtrace when HAVE_FUNCTION_TRACER is enable
@ 2012-08-13 15:44       ` Akhilesh Kumar
  0 siblings, 0 replies; 7+ messages in thread
From: Akhilesh Kumar @ 2012-08-13 15:44 UTC (permalink / raw)
  To: ralf, Wu Zhangjin; +Cc: linux-mips

[-- Attachment #1: Type: text/plain, Size: 14587 bytes --]

Hi Ralf/John,

Detail Description is added in the patch

Thanks,
Akhilesh




From 89004f88a1f8399be7a856b43b475f06c3d5bb30 Mon Sep 17 00:00:00 2001
From:  Akhilesh Kumar <akhilesh.lxr@...com>
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
[<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
---------------------------------------------------------------------
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
[<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 instrumentation
code is:
- jal <ftrace_caller>
- 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>
---
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 <mcount>/<ftrace_caller> 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>/<ftrace_caller> */
+ 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 <akhilesh.lxr@gmail.com>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 <mcount>/<ftrace_caller> 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>/<ftrace_caller> */
> + 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 <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  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
>> > [<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
>> > ---------------------------------------------------------------------
>> > #> 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
>> > [<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 instrumentation
>> > code is:
>> >  - jal <ftrace_caller>
>> >  - 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>
>> > ---
>> >  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 <mcount>/<ftrace_caller> 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>/<ftrace_caller> */
>> > + int jal_mcount = 0;
>> > +#endif
>> > +
>> >   info->pc_offset = -1;
>> >   info->frame_size = 0;
>>
>
>

[-- Attachment #2: Type: text/html, Size: 20031 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Bug-fix] backtrace when HAVE_FUNCTION_TRACER is enable
  2012-08-13 15:44       ` Akhilesh Kumar
  (?)
@ 2012-08-13 16:47       ` Ralf Baechle
  2012-08-14 11:15         ` Ralf Baechle
  -1 siblings, 1 reply; 7+ messages in thread
From: Ralf Baechle @ 2012-08-13 16:47 UTC (permalink / raw)
  To: Akhilesh Kumar; +Cc: Wu Zhangjin, linux-mips

On Mon, Aug 13, 2012 at 09:14:38PM +0530, Akhilesh Kumar wrote:

> Detail Description is added in the patch

This patch is garbled and doesn't apply.  You can find some hints on
how to deal with patch-corrupting mail clients in:

  http://www.linux-mips.org/wiki/Mailing-patches


  Ralf

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Bug-fix] backtrace when HAVE_FUNCTION_TRACER is enable
  2012-08-13 16:47       ` Ralf Baechle
@ 2012-08-14 11:15         ` Ralf Baechle
  0 siblings, 0 replies; 7+ messages in thread
From: Ralf Baechle @ 2012-08-14 11:15 UTC (permalink / raw)
  To: Akhilesh Kumar; +Cc: Wu Zhangjin, linux-mips

On Mon, Aug 13, 2012 at 06:47:17PM +0200, Ralf Baechle wrote:

> 
> > Detail Description is added in the patch
> 
> This patch is garbled and doesn't apply.  You can find some hints on
> how to deal with patch-corrupting mail clients in:
> 
>   http://www.linux-mips.org/wiki/Mailing-patches

Also it appears to be incomplete.  I see your patch plenty of macro
definitions and function declarations but nothing appears to use them.

  Ralf

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2012-08-14 11:15 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-09 13:53 [Bug-fix] backtrace when HAVE_FUNCTION_TRACER is enable Akhilesh Kumar
     [not found] ` <CAD+V5YKZJHKONehvT+-GrKLP2+e0PiLiFTJWEojiDoNyLT3yGQ@mail.gmail.com>
2012-08-09 17:16   ` Akhilesh Kumar
2012-08-12  6:28     ` John Crispin
2012-08-13 15:44     ` Akhilesh Kumar
2012-08-13 15:44       ` Akhilesh Kumar
2012-08-13 16:47       ` Ralf Baechle
2012-08-14 11:15         ` Ralf Baechle

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.