diff options
author | Stuart Menefy <stuart.menefy@st.com> | 2009-07-29 10:01:24 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-07-29 10:01:24 -0400 |
commit | fd78a76aefb5bf28a11d6960d29e03a11db62320 (patch) | |
tree | 8dac39f13c9b3bdadda02594f49501b5522ecad7 /arch/sh/kernel/entry-common.S | |
parent | 82b242214b6f5b96eb9b76452ac6e2b67dd81abd (diff) |
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>
Diffstat (limited to 'arch/sh/kernel/entry-common.S')
-rw-r--r-- | arch/sh/kernel/entry-common.S | 63 |
1 files changed, 16 insertions, 47 deletions
diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index d62175650c54..fc26ccd82789 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S | |||
@@ -45,7 +45,7 @@ | |||
45 | */ | 45 | */ |
46 | 46 | ||
47 | #if defined(CONFIG_PREEMPT) | 47 | #if defined(CONFIG_PREEMPT) |
48 | # define preempt_stop() cli | 48 | # define preempt_stop() cli ; TRACE_IRQS_OFF |
49 | #else | 49 | #else |
50 | # define preempt_stop() | 50 | # define preempt_stop() |
51 | # define resume_kernel __restore_all | 51 | # define resume_kernel __restore_all |
@@ -55,11 +55,7 @@ | |||
55 | .align 2 | 55 | .align 2 |
56 | ENTRY(exception_error) | 56 | ENTRY(exception_error) |
57 | ! | 57 | ! |
58 | #ifdef CONFIG_TRACE_IRQFLAGS | 58 | TRACE_IRQS_ON |
59 | mov.l 2f, r0 | ||
60 | jsr @r0 | ||
61 | nop | ||
62 | #endif | ||
63 | sti | 59 | sti |
64 | mov.l 1f, r0 | 60 | mov.l 1f, r0 |
65 | jmp @r0 | 61 | jmp @r0 |
@@ -67,22 +63,23 @@ ENTRY(exception_error) | |||
67 | 63 | ||
68 | .align 2 | 64 | .align 2 |
69 | 1: .long do_exception_error | 65 | 1: .long do_exception_error |
70 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
71 | 2: .long trace_hardirqs_on | ||
72 | #endif | ||
73 | 66 | ||
74 | .align 2 | 67 | .align 2 |
75 | ret_from_exception: | 68 | ret_from_exception: |
76 | preempt_stop() | 69 | preempt_stop() |
77 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
78 | mov.l 4f, r0 | ||
79 | jsr @r0 | ||
80 | nop | ||
81 | #endif | ||
82 | ENTRY(ret_from_irq) | 70 | ENTRY(ret_from_irq) |
83 | ! | 71 | ! |
84 | mov #OFF_SR, r0 | 72 | mov #OFF_SR, r0 |
85 | mov.l @(r0,r15), r0 ! get status register | 73 | 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 | ||
86 | shll r0 | 83 | shll r0 |
87 | shll r0 ! kernel space? | 84 | shll r0 ! kernel space? |
88 | get_current_thread_info r8, r0 | 85 | get_current_thread_info r8, r0 |
@@ -125,11 +122,7 @@ noresched: | |||
125 | ENTRY(resume_userspace) | 122 | ENTRY(resume_userspace) |
126 | ! r8: current_thread_info | 123 | ! r8: current_thread_info |
127 | cli | 124 | cli |
128 | #ifdef CONFIG_TRACE_IRQFLAGS | 125 | TRACE_IRQS_OfF |
129 | mov.l 5f, r0 | ||
130 | jsr @r0 | ||
131 | nop | ||
132 | #endif | ||
133 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags | 126 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags |
134 | tst #(_TIF_WORK_MASK & 0xff), r0 | 127 | tst #(_TIF_WORK_MASK & 0xff), r0 |
135 | bt/s __restore_all | 128 | bt/s __restore_all |
@@ -156,11 +149,7 @@ work_resched: | |||
156 | jsr @r1 ! schedule | 149 | jsr @r1 ! schedule |
157 | nop | 150 | nop |
158 | cli | 151 | cli |
159 | #ifdef CONFIG_TRACE_IRQFLAGS | 152 | TRACE_IRQS_OFF |
160 | mov.l 5f, r0 | ||
161 | jsr @r0 | ||
162 | nop | ||
163 | #endif | ||
164 | ! | 153 | ! |
165 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags | 154 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags |
166 | tst #(_TIF_WORK_MASK & 0xff), r0 | 155 | tst #(_TIF_WORK_MASK & 0xff), r0 |
@@ -172,10 +161,6 @@ work_resched: | |||
172 | 1: .long schedule | 161 | 1: .long schedule |
173 | 2: .long do_notify_resume | 162 | 2: .long do_notify_resume |
174 | 3: .long resume_userspace | 163 | 3: .long resume_userspace |
175 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
176 | 4: .long trace_hardirqs_on | ||
177 | 5: .long trace_hardirqs_off | ||
178 | #endif | ||
179 | 164 | ||
180 | .align 2 | 165 | .align 2 |
181 | syscall_exit_work: | 166 | syscall_exit_work: |
@@ -184,11 +169,7 @@ syscall_exit_work: | |||
184 | tst #(_TIF_WORK_SYSCALL_MASK & 0xff), r0 | 169 | tst #(_TIF_WORK_SYSCALL_MASK & 0xff), r0 |
185 | bt/s work_pending | 170 | bt/s work_pending |
186 | tst #_TIF_NEED_RESCHED, r0 | 171 | tst #_TIF_NEED_RESCHED, r0 |
187 | #ifdef CONFIG_TRACE_IRQFLAGS | 172 | TRACE_IRQS_ON |
188 | mov.l 5f, r0 | ||
189 | jsr @r0 | ||
190 | nop | ||
191 | #endif | ||
192 | sti | 173 | sti |
193 | mov r15, r4 | 174 | mov r15, r4 |
194 | mov.l 8f, r0 ! do_syscall_trace_leave | 175 | mov.l 8f, r0 ! do_syscall_trace_leave |
@@ -321,11 +302,7 @@ ENTRY(system_call) | |||
321 | bt/s debug_trap ! it's a debug trap.. | 302 | bt/s debug_trap ! it's a debug trap.. |
322 | nop | 303 | nop |
323 | 304 | ||
324 | #ifdef CONFIG_TRACE_IRQFLAGS | 305 | TRACE_IRQS_ON |
325 | mov.l 5f, r10 | ||
326 | jsr @r10 | ||
327 | nop | ||
328 | #endif | ||
329 | sti | 306 | sti |
330 | 307 | ||
331 | ! | 308 | ! |
@@ -355,11 +332,7 @@ syscall_call: | |||
355 | ! | 332 | ! |
356 | syscall_exit: | 333 | syscall_exit: |
357 | cli | 334 | cli |
358 | #ifdef CONFIG_TRACE_IRQFLAGS | 335 | TRACE_IRQS_OFF |
359 | mov.l 6f, r0 | ||
360 | jsr @r0 | ||
361 | nop | ||
362 | #endif | ||
363 | ! | 336 | ! |
364 | get_current_thread_info r8, r0 | 337 | get_current_thread_info r8, r0 |
365 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags | 338 | mov.l @(TI_FLAGS,r8), r0 ! current_thread_info->flags |
@@ -377,9 +350,5 @@ syscall_exit: | |||
377 | #endif | 350 | #endif |
378 | 2: .long NR_syscalls | 351 | 2: .long NR_syscalls |
379 | 3: .long sys_call_table | 352 | 3: .long sys_call_table |
380 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
381 | 5: .long trace_hardirqs_on | ||
382 | 6: .long trace_hardirqs_off | ||
383 | #endif | ||
384 | 7: .long do_syscall_trace_enter | 353 | 7: .long do_syscall_trace_enter |
385 | 8: .long do_syscall_trace_leave | 354 | 8: .long do_syscall_trace_leave |