Skip to content

Commit fd78a76

Browse files
Stuart Menefypmundt
Stuart Menefy
authored andcommitted
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>
1 parent 82b2422 commit fd78a76

File tree

5 files changed

+96
-53
lines changed

5 files changed

+96
-53
lines changed

arch/sh/Kconfig.debug

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ config EARLY_SCIF_CONSOLE_PORT
3838
default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \
3939
CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \
4040
CPU_SUBTYPE_SH7343
41-
default "0xffea0000" if CPU_SUBTYPE_SH7785
41+
default "0xffeb0000" if CPU_SUBTYPE_SH7785
4242
default "0xffeb0000" if CPU_SUBTYPE_SH7786
4343
default "0xfffe8000" if CPU_SUBTYPE_SH7203
4444
default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263

arch/sh/include/asm/entry-macros.S

+72
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,78 @@
3131
#endif
3232
.endm
3333

34+
#ifdef CONFIG_TRACE_IRQFLAGS
35+
36+
.macro TRACE_IRQS_ON
37+
mov.l r0, @-r15
38+
mov.l r1, @-r15
39+
mov.l r2, @-r15
40+
mov.l r3, @-r15
41+
mov.l r4, @-r15
42+
mov.l r5, @-r15
43+
mov.l r6, @-r15
44+
mov.l r7, @-r15
45+
46+
mov.l 7834f, r0
47+
jsr @r0
48+
nop
49+
50+
mov.l @r15+, r7
51+
mov.l @r15+, r6
52+
mov.l @r15+, r5
53+
mov.l @r15+, r4
54+
mov.l @r15+, r3
55+
mov.l @r15+, r2
56+
mov.l @r15+, r1
57+
mov.l @r15+, r0
58+
mov.l 7834f, r0
59+
60+
bra 7835f
61+
nop
62+
.balign 4
63+
7834: .long trace_hardirqs_on
64+
7835:
65+
.endm
66+
.macro TRACE_IRQS_OFF
67+
68+
mov.l r0, @-r15
69+
mov.l r1, @-r15
70+
mov.l r2, @-r15
71+
mov.l r3, @-r15
72+
mov.l r4, @-r15
73+
mov.l r5, @-r15
74+
mov.l r6, @-r15
75+
mov.l r7, @-r15
76+
77+
mov.l 7834f, r0
78+
jsr @r0
79+
nop
80+
81+
mov.l @r15+, r7
82+
mov.l @r15+, r6
83+
mov.l @r15+, r5
84+
mov.l @r15+, r4
85+
mov.l @r15+, r3
86+
mov.l @r15+, r2
87+
mov.l @r15+, r1
88+
mov.l @r15+, r0
89+
mov.l 7834f, r0
90+
91+
bra 7835f
92+
nop
93+
.balign 4
94+
7834: .long trace_hardirqs_off
95+
7835:
96+
.endm
97+
98+
#else
99+
.macro TRACE_IRQS_ON
100+
.endm
101+
102+
.macro TRACE_IRQS_OFF
103+
.endm
104+
#endif
105+
34106
#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
35107
# define PREF(x) pref @x
36108
#else

arch/sh/kernel/entry-common.S

+16-47
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
*/
4646

4747
#if defined(CONFIG_PREEMPT)
48-
# define preempt_stop() cli
48+
# define preempt_stop() cli ; TRACE_IRQS_OFF
4949
#else
5050
# define preempt_stop()
5151
# define resume_kernel __restore_all
@@ -55,34 +55,31 @@
5555
.align 2
5656
ENTRY(exception_error)
5757
!
58-
#ifdef CONFIG_TRACE_IRQFLAGS
59-
mov.l 2f, r0
60-
jsr @r0
61-
nop
62-
#endif
58+
TRACE_IRQS_ON
6359
sti
6460
mov.l 1f, r0
6561
jmp @r0
6662
nop
6763

6864
.align 2
6965
1: .long do_exception_error
70-
#ifdef CONFIG_TRACE_IRQFLAGS
71-
2: .long trace_hardirqs_on
72-
#endif
7366

7467
.align 2
7568
ret_from_exception:
7669
preempt_stop()
77-
#ifdef CONFIG_TRACE_IRQFLAGS
78-
mov.l 4f, r0
79-
jsr @r0
80-
nop
81-
#endif
8270
ENTRY(ret_from_irq)
8371
!
8472
mov #OFF_SR, r0
8573
mov.l @(r0,r15), r0 ! get status register
74+
75+
shlr2 r0
76+
and #0x3c, r0
77+
cmp/eq #0x3c, r0
78+
bt 9f
79+
TRACE_IRQS_ON
80+
9:
81+
mov #OFF_SR, r0
82+
mov.l @(r0,r15), r0 ! get status register
8683
shll r0
8784
shll r0 ! kernel space?
8885
get_current_thread_info r8, r0
@@ -125,11 +122,7 @@ noresched:
125122
ENTRY(resume_userspace)
126123
! r8: current_thread_info
127124
cli
128-
#ifdef CONFIG_TRACE_IRQFLAGS
129-
mov.l 5f, r0
130-
jsr @r0
131-
nop
132-
#endif
125+
TRACE_IRQS_OfF
133126
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
134127
tst #(_TIF_WORK_MASK & 0xff), r0
135128
bt/s __restore_all
@@ -156,11 +149,7 @@ work_resched:
156149
jsr @r1 ! schedule
157150
nop
158151
cli
159-
#ifdef CONFIG_TRACE_IRQFLAGS
160-
mov.l 5f, r0
161-
jsr @r0
162-
nop
163-
#endif
152+
TRACE_IRQS_OFF
164153
!
165154
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
166155
tst #(_TIF_WORK_MASK & 0xff), r0
@@ -172,10 +161,6 @@ work_resched:
172161
1: .long schedule
173162
2: .long do_notify_resume
174163
3: .long resume_userspace
175-
#ifdef CONFIG_TRACE_IRQFLAGS
176-
4: .long trace_hardirqs_on
177-
5: .long trace_hardirqs_off
178-
#endif
179164

180165
.align 2
181166
syscall_exit_work:
@@ -184,11 +169,7 @@ syscall_exit_work:
184169
tst #(_TIF_WORK_SYSCALL_MASK & 0xff), r0
185170
bt/s work_pending
186171
tst #_TIF_NEED_RESCHED, r0
187-
#ifdef CONFIG_TRACE_IRQFLAGS
188-
mov.l 5f, r0
189-
jsr @r0
190-
nop
191-
#endif
172+
TRACE_IRQS_ON
192173
sti
193174
mov r15, r4
194175
mov.l 8f, r0 ! do_syscall_trace_leave
@@ -321,11 +302,7 @@ ENTRY(system_call)
321302
bt/s debug_trap ! it's a debug trap..
322303
nop
323304

324-
#ifdef CONFIG_TRACE_IRQFLAGS
325-
mov.l 5f, r10
326-
jsr @r10
327-
nop
328-
#endif
305+
TRACE_IRQS_ON
329306
sti
330307

331308
!
@@ -355,11 +332,7 @@ syscall_call:
355332
!
356333
syscall_exit:
357334
cli
358-
#ifdef CONFIG_TRACE_IRQFLAGS
359-
mov.l 6f, r0
360-
jsr @r0
361-
nop
362-
#endif
335+
TRACE_IRQS_OFF
363336
!
364337
get_current_thread_info r8, r0
365338
mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags
@@ -377,9 +350,5 @@ syscall_exit:
377350
#endif
378351
2: .long NR_syscalls
379352
3: .long sys_call_table
380-
#ifdef CONFIG_TRACE_IRQFLAGS
381-
5: .long trace_hardirqs_on
382-
6: .long trace_hardirqs_off
383-
#endif
384353
7: .long do_syscall_trace_enter
385354
8: .long do_syscall_trace_leave

arch/sh/kernel/io_trapped.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -112,22 +112,23 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
112112
struct trapped_io *tiop;
113113
struct resource *res;
114114
int k, len;
115+
unsigned long flags;
115116

116-
spin_lock_irq(&trapped_lock);
117+
spin_lock_irqsave(&trapped_lock, flags);
117118
list_for_each_entry(tiop, list, list) {
118119
voffs = 0;
119120
for (k = 0; k < tiop->num_resources; k++) {
120121
res = tiop->resource + k;
121122
if (res->start == offset) {
122-
spin_unlock_irq(&trapped_lock);
123+
spin_unlock_irqrestore(&trapped_lock, flags);
123124
return tiop->virt_base + voffs;
124125
}
125126

126127
len = (res->end - res->start) + 1;
127128
voffs += roundup(len, PAGE_SIZE);
128129
}
129130
}
130-
spin_unlock_irq(&trapped_lock);
131+
spin_unlock_irqrestore(&trapped_lock, flags);
131132
return NULL;
132133
}
133134
EXPORT_SYMBOL_GPL(match_trapped_io_handler);

drivers/serial/sh-sci.c

+3-2
Original file line numberDiff line numberDiff line change
@@ -662,10 +662,11 @@ static irqreturn_t sci_rx_interrupt(int irq, void *port)
662662
static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
663663
{
664664
struct uart_port *port = ptr;
665+
unsigned long flags;
665666

666-
spin_lock_irq(&port->lock);
667+
spin_lock_irqsave(&port->lock, flags);
667668
sci_transmit_chars(port);
668-
spin_unlock_irq(&port->lock);
669+
spin_unlock_irqrestore(&port->lock, flags);
669670

670671
return IRQ_HANDLED;
671672
}

0 commit comments

Comments
 (0)