summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaro Koskinen <aaro.koskinen@nsn.com>2014-10-17 19:10:26 +0400
committerRalf Baechle <ralf@linux-mips.org>2014-11-24 09:45:31 +0300
commit569309b42fc67a8b42f57adb68764bd10bcf2178 (patch)
tree0659cf0719432f681da4287d9e7ece66ab6f1322
parent1b48142a809ee03f48979fad647245dbe0ce423a (diff)
downloadlinux-569309b42fc67a8b42f57adb68764bd10bcf2178.tar.xz
MIPS: oprofile: Backtrace: don't fail on leaf functions
Continue the backtrace if we cannot find SP adjustment and RA save. In that case, just assume the current RA. This allows us to get samples of frequent callers of e.g. GLIBC memset(). Signed-off-by: Aaro Koskinen <aaro.koskinen@nsn.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/8109/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/oprofile/backtrace.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/arch/mips/oprofile/backtrace.c b/arch/mips/oprofile/backtrace.c
index 83a1dfd8f0e3..5e645c9a3162 100644
--- a/arch/mips/oprofile/backtrace.c
+++ b/arch/mips/oprofile/backtrace.c
@@ -65,7 +65,7 @@ static inline int is_end_of_function_marker(union mips_instruction *ip)
* - handle cases where the stack is adjusted inside a function
* (generally doesn't happen)
* - find optimal value for max_instr_check
- * - try to find a way to handle leaf functions
+ * - try to find a better way to handle leaf functions
*/
static inline int unwind_user_frame(struct stackframe *old_frame,
@@ -104,7 +104,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame,
}
if (!ra_offset || !stack_size)
- return -1;
+ goto done;
if (ra_offset) {
new_frame.ra = old_frame->sp + ra_offset;
@@ -121,6 +121,7 @@ static inline int unwind_user_frame(struct stackframe *old_frame,
if (new_frame.sp > old_frame->sp)
return -2;
+done:
new_frame.pc = old_frame->ra;
*old_frame = new_frame;