summary refs log tree commit diff
diff options
context:
space:
mode:
authorAaro Koskinen <aaro.koskinen@nokia.com>2015-10-23 15:39:02 +0300
committerRalf Baechle <ralf@linux-mips.org>2015-11-11 08:36:46 +0100
commite1e1611598148e03c6d65e6c23338f4ff2cee71e (patch)
tree060f9704cc326ffb3d3554b60751923a114f7eda
parent972cfd5502cc87d388a6d358eae717ac48ca4817 (diff)
downloadlinux-e1e1611598148e03c6d65e6c23338f4ff2cee71e.tar.gz
MIPS: Add LATENCYTOP support
Add LATENCYTOP support for MIPS. Tested on OCTEON.

Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/11353/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
-rw-r--r--arch/mips/Kconfig4
-rw-r--r--arch/mips/kernel/stacktrace.c27
2 files changed, 19 insertions, 12 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 2f45c866e7ca..10feb1520b0c 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2759,6 +2759,10 @@ config STACKTRACE_SUPPORT
 	bool
 	default y
 
+config HAVE_LATENCYTOP_SUPPORT
+	bool
+	default y
+
 config PGTABLE_LEVELS
 	int
 	default 3 if 64BIT && !PAGE_SIZE_64KB
diff --git a/arch/mips/kernel/stacktrace.c b/arch/mips/kernel/stacktrace.c
index 1ba775d24d38..506021f62549 100644
--- a/arch/mips/kernel/stacktrace.c
+++ b/arch/mips/kernel/stacktrace.c
@@ -12,14 +12,15 @@
  * Save stack-backtrace addresses into a stack_trace buffer:
  */
 static void save_raw_context_stack(struct stack_trace *trace,
-	unsigned long reg29)
+	unsigned long reg29, int savesched)
 {
 	unsigned long *sp = (unsigned long *)reg29;
 	unsigned long addr;
 
 	while (!kstack_end(sp)) {
 		addr = *sp++;
-		if (__kernel_text_address(addr)) {
+		if (__kernel_text_address(addr) &&
+		    (savesched || !in_sched_functions(addr))) {
 			if (trace->skip > 0)
 				trace->skip--;
 			else
@@ -31,7 +32,7 @@ static void save_raw_context_stack(struct stack_trace *trace,
 }
 
 static void save_context_stack(struct stack_trace *trace,
-	struct task_struct *tsk, struct pt_regs *regs)
+	struct task_struct *tsk, struct pt_regs *regs, int savesched)
 {
 	unsigned long sp = regs->regs[29];
 #ifdef CONFIG_KALLSYMS
@@ -43,20 +44,22 @@ static void save_context_stack(struct stack_trace *trace,
 			(unsigned long)task_stack_page(tsk);
 		if (stack_page && sp >= stack_page &&
 		    sp <= stack_page + THREAD_SIZE - 32)
-			save_raw_context_stack(trace, sp);
+			save_raw_context_stack(trace, sp, savesched);
 		return;
 	}
 	do {
-		if (trace->skip > 0)
-			trace->skip--;
-		else
-			trace->entries[trace->nr_entries++] = pc;
-		if (trace->nr_entries >= trace->max_entries)
-			break;
+		if (savesched || !in_sched_functions(pc)) {
+			if (trace->skip > 0)
+				trace->skip--;
+			else
+				trace->entries[trace->nr_entries++] = pc;
+			if (trace->nr_entries >= trace->max_entries)
+				break;
+		}
 		pc = unwind_stack(tsk, &sp, pc, &ra);
 	} while (pc);
 #else
-	save_raw_context_stack(trace, sp);
+	save_raw_context_stack(trace, sp, savesched);
 #endif
 }
 
@@ -82,6 +85,6 @@ void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 		regs->cp0_epc = tsk->thread.reg31;
 	} else
 		prepare_frametrace(regs);
-	save_context_stack(trace, tsk, regs);
+	save_context_stack(trace, tsk, regs, tsk == current);
 }
 EXPORT_SYMBOL_GPL(save_stack_trace_tsk);