Commit fd78a76a authored by Stuart Menefy's avatar Stuart Menefy Committed by Paul Mundt

sh: Rework irqflags tracing to fix up CONFIG_PROVE_LOCKING.

This cleans up the irqflags tracing code quite a bit and ties it
in to various missing callsites that caused an imbalance when
CONFIG_PROVE_LOCKING was enabled.

Previously this was catching on:

 987 #ifdef CONFIG_PROVE_LOCKING
 988     DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
 989     DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
 990 #endif
 991     retval = -EAGAIN;

with hardirqs being doubly enabled, and subsequently bailing out
with the following call trace:

	Call trace:
	[<88035224>] __lock_acquire+0x616/0x6a6
	[<88015a8c>] do_fork+0xf8/0x2b0
	[<880331ec>] trace_hardirqs_on_caller+0xd4/0x114
	[<88241074>] _spin_unlock_irq+0x20/0x64
	[<88035224>] __lock_acquire+0x616/0x6a6
	[<8800386c>] kernel_thread+0x48/0x70
	[<88024ecc>] ____call_usermodehelper+0x0/0x110
	[<88024ecc>] ____call_usermodehelper+0x0/0x110
	[<88003894>] kernel_thread_helper+0x0/0x14
	[<88024bac>] __call_usermodehelper+0x38/0x70
	[<88025dc0>] worker_thread+0x150/0x274
	[<88035b9c>] lock_release+0x0/0x198
	[<88024b74>] __call_usermodehelper+0x0/0x70
	[<88028cf0>] autoremove_wake_function+0x0/0x30
	[<88028bf2>] kthread+0x3e/0x70
	[<88025c70>] worker_thread+0x0/0x274
	[<8800389c>] kernel_thread_helper+0x8/0x14
	[<88028bb4>] kthread+0x0/0x70
	[<88003894>] kernel_thread_helper+0x0/0x14
Reported-by: default avatarNobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com>
Signed-off-by: default avatarStuart Menefy <stuart.menefy@st.com>
Signed-off-by: default avatarMatt Fleming <matt@console-pimps.org>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 82b24221
...@@ -38,7 +38,7 @@ config EARLY_SCIF_CONSOLE_PORT ...@@ -38,7 +38,7 @@ config EARLY_SCIF_CONSOLE_PORT
default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \ default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \
CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \ CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \
CPU_SUBTYPE_SH7343 CPU_SUBTYPE_SH7343
default "0xffea0000" if CPU_SUBTYPE_SH7785 default "0xffeb0000" if CPU_SUBTYPE_SH7785
default "0xffeb0000" if CPU_SUBTYPE_SH7786 default "0xffeb0000" if CPU_SUBTYPE_SH7786
default "0xfffe8000" if CPU_SUBTYPE_SH7203 default "0xfffe8000" if CPU_SUBTYPE_SH7203
default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263 default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263
......
...@@ -31,6 +31,78 @@ ...@@ -31,6 +31,78 @@
#endif #endif
.endm .endm
#ifdef CONFIG_TRACE_IRQFLAGS
.macro TRACE_IRQS_ON
mov.l r0, @-r15
mov.l r1, @-r15
mov.l r2, @-r15
mov.l r3, @-r15
mov.l r4, @-r15
mov.l r5, @-r15
mov.l r6, @-r15
mov.l r7, @-r15
mov.l 7834f, r0
jsr @r0
nop
mov.l @r15+, r7
mov.l @r15+, r6
mov.l @r15+, r5
mov.l @r15+, r4
mov.l @r15+, r3
mov.l @r15+, r2
mov.l @r15+, r1
mov.l @r15+, r0
mov.l 7834f, r0
bra 7835f
nop
.balign 4
7834: .long trace_hardirqs_on
7835:
.endm
.macro TRACE_IRQS_OFF
mov.l r0, @-r15
mov.l r1, @-r15
mov.l r2, @-r15
mov.l r3, @-r15
mov.l r4, @-r15
mov.l r5, @-r15
mov.l r6, @-r15
mov.l r7, @-r15
mov.l 7834f, r0
jsr @r0
nop
mov.l @r15+, r7
mov.l @r15+, r6
mov.l @r15+, r5
mov.l @r15+, r4
mov.l @r15+, r3
mov.l @r15+, r2
mov.l @r15+, r1
mov.l @r15+, r0
mov.l 7834f, r0
bra 7835f
nop
.balign 4
7834: .long trace_hardirqs_off
7835:
.endm
#else
.macro TRACE_IRQS_ON
.endm
.macro TRACE_IRQS_OFF
.endm
#endif
#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4) #if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
# define PREF(x) pref @x # define PREF(x) pref @x
#else #else
......
...@@ -45,7 +45,7 @@ ...@@ -45,7 +45,7 @@
*/ */
#if defined(CONFIG_PREEMPT) #if defined(CONFIG_PREEMPT)
# define preempt_stop() cli # define preempt_stop() cli ; TRACE_IRQS_OFF
#else #else
# define preempt_stop() # define preempt_stop()
# define resume_kernel __restore_all # define resume_kernel __restore_all
...@@ -55,11 +55,7 @@ ...@@ -55,11 +55,7 @@
.align 2 .align 2
ENTRY(exception_error) ENTRY(exception_error)
! !
#ifdef CONFIG_TRACE_IRQFLAGS TRACE_IRQS_ON
mov.l 2f, r0
jsr @r0
nop
#endif
sti sti
mov.l 1f, r0 mov.l 1f, r0
jmp @r0 jmp @r0
...@@ -67,22 +63,23 @@ ENTRY(exception_error) ...@@ -67,22 +63,23 @@ ENTRY(exception_error)
.align 2 .align 2
1: .long do_exception_error 1: .long do_exception_error
#ifdef CONFIG_TRACE_IRQFLAGS
2: .long trace_hardirqs_on
#endif
.align 2 .align 2
ret_from_exception: ret_from_exception:
preempt_stop() preempt_stop()
#ifdef CONFIG_TRACE_IRQFLAGS
mov.l 4f, r0
jsr @r0
nop
#endif
ENTRY(ret_from_irq) ENTRY(ret_from_irq)
! !
mov #OFF_SR, r0 mov #OFF_SR, r0
mov.l @(r0,r15), r0 ! get status register mov.l @(r0,r15), r0 ! get status register
shlr2 r0
and #0x3c, r0
cmp/eq #0x3c, r0
bt 9f
TRACE_IRQS_ON
9:
mov #OFF_SR, r0
mov.l @(r0,r15), r0 ! get status register
shll r0 shll r0
shll r0 ! kernel space? shll r0 ! kernel space?
get_current_thread_info r8, r0 get_current_thread_info r8, r0
...@@ -125,11 +122,7 @@ noresched: ...@@ -125,11 +122,7 @@ noresched:
ENTRY(resume_userspace) ENTRY(resume_userspace)
! r8: current_thread_info ! r8: current_thread_info
cli cli
#ifdef CONFIG_TRACE_IRQFLAGS TRACE_IRQS_OfF
mov.l 5f, r0
jsr @r0
nop
#endif
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
tst #(_TIF_WORK_MASK & 0xff), r0 tst #(_TIF_WORK_MASK & 0xff), r0
bt/s __restore_all bt/s __restore_all
...@@ -156,11 +149,7 @@ work_resched: ...@@ -156,11 +149,7 @@ work_resched:
jsr @r1 ! schedule jsr @r1 ! schedule
nop nop
cli cli
#ifdef CONFIG_TRACE_IRQFLAGS TRACE_IRQS_OFF
mov.l 5f, r0
jsr @r0
nop
#endif
! !
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
tst #(_TIF_WORK_MASK & 0xff), r0 tst #(_TIF_WORK_MASK & 0xff), r0
...@@ -172,10 +161,6 @@ work_resched: ...@@ -172,10 +161,6 @@ work_resched:
1: .long schedule 1: .long schedule
2: .long do_notify_resume 2: .long do_notify_resume
3: .long resume_userspace 3: .long resume_userspace
#ifdef CONFIG_TRACE_IRQFLAGS
4: .long trace_hardirqs_on
5: .long trace_hardirqs_off
#endif
.align 2 .align 2
syscall_exit_work: syscall_exit_work:
...@@ -184,11 +169,7 @@ syscall_exit_work: ...@@ -184,11 +169,7 @@ syscall_exit_work:
tst #(_TIF_WORK_SYSCALL_MASK & 0xff), r0 tst #(_TIF_WORK_SYSCALL_MASK & 0xff), r0
bt/s work_pending bt/s work_pending
tst #_TIF_NEED_RESCHED, r0 tst #_TIF_NEED_RESCHED, r0
#ifdef CONFIG_TRACE_IRQFLAGS TRACE_IRQS_ON
mov.l 5f, r0
jsr @r0
nop
#endif
sti sti
mov r15, r4 mov r15, r4
mov.l 8f, r0 ! do_syscall_trace_leave mov.l 8f, r0 ! do_syscall_trace_leave
...@@ -321,11 +302,7 @@ ENTRY(system_call) ...@@ -321,11 +302,7 @@ ENTRY(system_call)
bt/s debug_trap ! it's a debug trap.. bt/s debug_trap ! it's a debug trap..
nop nop
#ifdef CONFIG_TRACE_IRQFLAGS TRACE_IRQS_ON
mov.l 5f, r10
jsr @r10
nop
#endif
sti sti
! !
...@@ -355,11 +332,7 @@ syscall_call: ...@@ -355,11 +332,7 @@ syscall_call:
! !
syscall_exit: syscall_exit:
cli cli
#ifdef CONFIG_TRACE_IRQFLAGS TRACE_IRQS_OFF
mov.l 6f, r0
jsr @r0
nop
#endif
! !
get_current_thread_info r8, r0 get_current_thread_info r8, r0
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
...@@ -377,9 +350,5 @@ syscall_exit: ...@@ -377,9 +350,5 @@ syscall_exit:
#endif #endif
2: .long NR_syscalls 2: .long NR_syscalls
3: .long sys_call_table 3: .long sys_call_table
#ifdef CONFIG_TRACE_IRQFLAGS
5: .long trace_hardirqs_on
6: .long trace_hardirqs_off
#endif
7: .long do_syscall_trace_enter 7: .long do_syscall_trace_enter
8: .long do_syscall_trace_leave 8: .long do_syscall_trace_leave
...@@ -112,14 +112,15 @@ void __iomem *match_trapped_io_handler(struct list_head *list, ...@@ -112,14 +112,15 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
struct trapped_io *tiop; struct trapped_io *tiop;
struct resource *res; struct resource *res;
int k, len; int k, len;
unsigned long flags;
spin_lock_irq(&trapped_lock); spin_lock_irqsave(&trapped_lock, flags);
list_for_each_entry(tiop, list, list) { list_for_each_entry(tiop, list, list) {
voffs = 0; voffs = 0;
for (k = 0; k < tiop->num_resources; k++) { for (k = 0; k < tiop->num_resources; k++) {
res = tiop->resource + k; res = tiop->resource + k;
if (res->start == offset) { if (res->start == offset) {
spin_unlock_irq(&trapped_lock); spin_unlock_irqrestore(&trapped_lock, flags);
return tiop->virt_base + voffs; return tiop->virt_base + voffs;
} }
...@@ -127,7 +128,7 @@ void __iomem *match_trapped_io_handler(struct list_head *list, ...@@ -127,7 +128,7 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
voffs += roundup(len, PAGE_SIZE); voffs += roundup(len, PAGE_SIZE);
} }
} }
spin_unlock_irq(&trapped_lock); spin_unlock_irqrestore(&trapped_lock, flags);
return NULL; return NULL;
} }
EXPORT_SYMBOL_GPL(match_trapped_io_handler); EXPORT_SYMBOL_GPL(match_trapped_io_handler);
......
...@@ -662,10 +662,11 @@ static irqreturn_t sci_rx_interrupt(int irq, void *port) ...@@ -662,10 +662,11 @@ static irqreturn_t sci_rx_interrupt(int irq, void *port)
static irqreturn_t sci_tx_interrupt(int irq, void *ptr) static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
{ {
struct uart_port *port = ptr; struct uart_port *port = ptr;
unsigned long flags;
spin_lock_irq(&port->lock); spin_lock_irqsave(&port->lock, flags);
sci_transmit_chars(port); sci_transmit_chars(port);
spin_unlock_irq(&port->lock); spin_unlock_irqrestore(&port->lock, flags);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment