mirror of
https://github.com/adulau/aha.git
synced 2024-12-30 20:56:23 +00:00
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: Nobuhiro Iwamatsu <iwamatsu.nobuhiro@renesas.com> Signed-off-by: Stuart Menefy <stuart.menefy@st.com> Signed-off-by: Matt Fleming <matt@console-pimps.org> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
82b242214b
commit
fd78a76aef
5 changed files with 96 additions and 53 deletions
|
@ -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 @@
|
||||||
#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 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#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 @@
|
||||||
.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)
|
||||||
|
|
||||||
.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:
|
||||||
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:
|
||||||
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:
|
||||||
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:
|
||||||
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)
|
||||||
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:
|
||||||
!
|
!
|
||||||
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:
|
||||||
#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,
|
||||||
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,
|
||||||
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)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue