ARC: Add support for irqflags tracing and lockdep
authorVineet Gupta <vgupta@synopsys.com>
Fri, 6 Sep 2013 08:48:17 +0000 (14:18 +0530)
committerVineet Gupta <vgupta@synopsys.com>
Wed, 6 Nov 2013 05:11:40 +0000 (10:41 +0530)
Lockdep required a small fix to stacktrace API which was incorrectly
unwindign out of __switch_to for the current call frame.

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
arch/arc/Kconfig
arch/arc/include/asm/irqflags.h
arch/arc/kernel/entry.S
arch/arc/kernel/stacktrace.c

index 91dbb2757afd1d352d38faae2924c8861e435631..524e6fce2c899027b57f5784b88ece4023a87b41 100644 (file)
@@ -35,6 +35,12 @@ config ARC
        select PERF_USE_VMALLOC
        select HAVE_DEBUG_STACKOVERFLOW
 
+config TRACE_IRQFLAGS_SUPPORT
+       def_bool y
+
+config LOCKDEP_SUPPORT
+       def_bool y
+
 config SCHED_OMIT_FRAME_POINTER
        def_bool y
 
index b68b53f458d1bc07f89b5b64c8f9fd9dc84ba323..cb7efc29f16ff076778c254f97d17212c0631e89 100644 (file)
@@ -151,16 +151,38 @@ static inline void arch_unmask_irq(unsigned int irq)
 
 #else
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+
+.macro TRACE_ASM_IRQ_DISABLE
+       bl      trace_hardirqs_off
+.endm
+
+.macro TRACE_ASM_IRQ_ENABLE
+       bl      trace_hardirqs_on
+.endm
+
+#else
+
+.macro TRACE_ASM_IRQ_DISABLE
+.endm
+
+.macro TRACE_ASM_IRQ_ENABLE
+.endm
+
+#endif
+
 .macro IRQ_DISABLE  scratch
        lr      \scratch, [status32]
        bic     \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK)
        flag    \scratch
+       TRACE_ASM_IRQ_DISABLE
 .endm
 
 .macro IRQ_ENABLE  scratch
        lr      \scratch, [status32]
        or      \scratch, \scratch, (STATUS_E1_MASK | STATUS_E2_MASK)
        flag    \scratch
+       TRACE_ASM_IRQ_ENABLE
 .endm
 
 #endif /* __ASSEMBLY__ */
index daa0e7990270a6b8ba38de8cf2c0764a620fbb60..47d09d07f09371d62804680b18bfec19c5fbbe3d 100644 (file)
@@ -250,6 +250,14 @@ ARC_ENTRY handle_interrupt_level1
        lr  r0, [icause1]
        and r0, r0, 0x1f
 
+#ifdef CONFIG_TRACE_IRQFLAGS
+       ; icause1 needs to be read early, before calling tracing, which
+       ; can clobber scratch regs, hence use of stack to stash it
+       push r0
+       TRACE_ASM_IRQ_DISABLE
+       pop  r0
+#endif
+
        bl.d  @arch_do_IRQ
        mov r1, sp
 
@@ -570,6 +578,7 @@ resume_user_mode_begin:
        ; --- (Slow Path #2) pending signal  ---
        mov r0, sp      ; pt_regs for arg to do_signal()/do_notify_resume()
 
+       GET_CURR_THR_INFO_FLAGS   r9
        bbit0  r9, TIF_SIGPENDING, .Lchk_notify_resume
 
        ; Normal Trap/IRQ entry only saves Scratch (caller-saved) regs
@@ -635,6 +644,8 @@ resume_kernel_mode:
 
 restore_regs :
 
+       TRACE_ASM_IRQ_ENABLE
+
        lr      r10, [status32]
 
        ; Restore REG File. In case multiple Events outstanding,
index f8b7d880304dcc777db967a0d344515b2e6d2453..ab97b034922f035667fccc76263647f9e66db6cf 100644 (file)
@@ -237,11 +237,13 @@ unsigned int get_wchan(struct task_struct *tsk)
  */
 void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
 {
+       /* Assumes @tsk is sleeping so unwinds from __switch_to */
        arc_unwind_core(tsk, NULL, __collect_all_but_sched, trace);
 }
 
 void save_stack_trace(struct stack_trace *trace)
 {
-       arc_unwind_core(current, NULL, __collect_all, trace);
+       /* Pass NULL for task so it unwinds the current call frame */
+       arc_unwind_core(NULL, NULL, __collect_all, trace);
 }
 #endif