Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ config EARLY_SCIF_CONSOLE_PORT
	default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \
				CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \
				CPU_SUBTYPE_SH7343
	default "0xffea0000" if CPU_SUBTYPE_SH7785
	default "0xffeb0000" if CPU_SUBTYPE_SH7785
	default "0xffeb0000" if CPU_SUBTYPE_SH7786
	default "0xfffe8000" if CPU_SUBTYPE_SH7203
	default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263
+72 −0
Original line number Diff line number Diff line
@@ -31,6 +31,78 @@
#endif	
	.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)
# define PREF(x)	pref	@x
#else
+16 −47
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@
 */

#if defined(CONFIG_PREEMPT)
#  define preempt_stop()	cli
#  define preempt_stop()	cli ; TRACE_IRQS_OFF
#else
#  define preempt_stop()
#  define resume_kernel		__restore_all
@@ -55,11 +55,7 @@
	.align	2
ENTRY(exception_error)
	!
#ifdef CONFIG_TRACE_IRQFLAGS
	mov.l	2f, r0
	jsr	@r0
	 nop
#endif
	TRACE_IRQS_ON
	sti
	mov.l	1f, r0
	jmp	@r0
@@ -67,22 +63,23 @@ ENTRY(exception_error)

	.align	2
1:	.long	do_exception_error
#ifdef CONFIG_TRACE_IRQFLAGS
2:	.long	trace_hardirqs_on
#endif

	.align	2
ret_from_exception:
	preempt_stop()
#ifdef CONFIG_TRACE_IRQFLAGS
	mov.l	4f, r0
	jsr	@r0
	 nop
#endif
ENTRY(ret_from_irq)
	!
	mov	#OFF_SR, r0
	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		! kernel space?
	get_current_thread_info r8, r0
@@ -125,11 +122,7 @@ noresched:
ENTRY(resume_userspace)
	! r8: current_thread_info
	cli
#ifdef CONFIG_TRACE_IRQFLAGS
	mov.l	5f, r0
	jsr	@r0
	 nop
#endif
	TRACE_IRQS_OfF
	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
	tst	#(_TIF_WORK_MASK & 0xff), r0
	bt/s	__restore_all
@@ -156,11 +149,7 @@ work_resched:
	jsr	@r1				! schedule
	 nop
	cli
#ifdef CONFIG_TRACE_IRQFLAGS
	mov.l	5f, r0
	jsr	@r0
	 nop
#endif
	TRACE_IRQS_OFF
	!
	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
	tst	#(_TIF_WORK_MASK & 0xff), r0
@@ -172,10 +161,6 @@ work_resched:
1:	.long	schedule
2:	.long	do_notify_resume
3:	.long	resume_userspace
#ifdef CONFIG_TRACE_IRQFLAGS
4:	.long	trace_hardirqs_on
5:	.long	trace_hardirqs_off
#endif

	.align	2
syscall_exit_work:
@@ -184,11 +169,7 @@ syscall_exit_work:
	tst	#(_TIF_WORK_SYSCALL_MASK & 0xff), r0
	bt/s	work_pending
	 tst	#_TIF_NEED_RESCHED, r0
#ifdef CONFIG_TRACE_IRQFLAGS
	mov.l	5f, r0
	jsr	@r0
	 nop
#endif
	TRACE_IRQS_ON
	sti
	mov	r15, r4
	mov.l	8f, r0			! do_syscall_trace_leave
@@ -321,11 +302,7 @@ ENTRY(system_call)
	bt/s	debug_trap		! it's a debug trap..
	 nop

#ifdef CONFIG_TRACE_IRQFLAGS
	mov.l	5f, r10
	jsr	@r10
	 nop
#endif
	TRACE_IRQS_ON
	sti

	!
@@ -355,11 +332,7 @@ syscall_call:
	!
syscall_exit:
	cli
#ifdef CONFIG_TRACE_IRQFLAGS
	mov.l	6f, r0
	jsr	@r0
	 nop
#endif
	TRACE_IRQS_OFF
	!
	get_current_thread_info r8, r0
	mov.l	@(TI_FLAGS,r8), r0		! current_thread_info->flags
@@ -377,9 +350,5 @@ syscall_exit:
#endif
2:	.long	NR_syscalls
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
8:	.long	do_syscall_trace_leave
+4 −3
Original line number Diff line number Diff line
@@ -112,14 +112,15 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
	struct trapped_io *tiop;
	struct resource *res;
	int k, len;
	unsigned long flags;

	spin_lock_irq(&trapped_lock);
	spin_lock_irqsave(&trapped_lock, flags);
	list_for_each_entry(tiop, list, list) {
		voffs = 0;
		for (k = 0; k < tiop->num_resources; k++) {
			res = tiop->resource + k;
			if (res->start == offset) {
				spin_unlock_irq(&trapped_lock);
				spin_unlock_irqrestore(&trapped_lock, flags);
				return tiop->virt_base + voffs;
			}

@@ -127,7 +128,7 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
			voffs += roundup(len, PAGE_SIZE);
		}
	}
	spin_unlock_irq(&trapped_lock);
	spin_unlock_irqrestore(&trapped_lock, flags);
	return NULL;
}
EXPORT_SYMBOL_GPL(match_trapped_io_handler);
+3 −2
Original line number Diff line number Diff line
@@ -662,10 +662,11 @@ static irqreturn_t sci_rx_interrupt(int irq, void *port)
static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
{
	struct uart_port *port = ptr;
	unsigned long flags;

	spin_lock_irq(&port->lock);
	spin_lock_irqsave(&port->lock, flags);
	sci_transmit_chars(port);
	spin_unlock_irq(&port->lock);
	spin_unlock_irqrestore(&port->lock, flags);

	return IRQ_HANDLED;
}