MIPS: Add LATENCYTOP support
authorAaro Koskinen <aaro.koskinen@nokia.com>
Fri, 23 Oct 2015 12:39:02 +0000 (15:39 +0300)
committerRalf Baechle <ralf@linux-mips.org>
Wed, 11 Nov 2015 07:36:46 +0000 (08:36 +0100)
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>
arch/mips/Kconfig
arch/mips/kernel/stacktrace.c

index 2f45c866e7ca12dae7e06352ab5274f52587c850..10feb1520b0cc542077966d8daf0ac81f47747ed 100644 (file)
@@ -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
index 1ba775d24d38f890d4e29a2168b533870d7cfb8b..506021f62549d98c7bc8260b300c659fd0118834 100644 (file)
  * 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);