aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStuart Menefy <stuart.menefy@st.com>2009-07-29 10:01:24 -0400
committerPaul Mundt <lethal@linux-sh.org>2009-07-29 10:01:24 -0400
commitfd78a76aefb5bf28a11d6960d29e03a11db62320 (patch)
tree8dac39f13c9b3bdadda02594f49501b5522ecad7
parent82b242214b6f5b96eb9b76452ac6e2b67dd81abd (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>
-rw-r--r--arch/sh/Kconfig.debug2
-rw-r--r--arch/sh/include/asm/entry-macros.S72
-rw-r--r--arch/sh/kernel/entry-common.S63
-rw-r--r--arch/sh/kernel/io_trapped.c7
-rw-r--r--drivers/serial/sh-sci.c5
5 files changed, 96 insertions, 53 deletions
diff --git a/arch/sh/Kconfig.debug b/arch/sh/Kconfig.debug
index b440fd936714..a6dce41296e7 100644
--- a/arch/sh/Kconfig.debug
+++ b/arch/sh/Kconfig.debug
@@ -38,7 +38,7 @@ config EARLY_SCIF_CONSOLE_PORT
38 default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \ 38 default "0xffe00000" if CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7763 || \
39 CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \ 39 CPU_SUBTYPE_SH7722 || CPU_SUBTYPE_SH7366 || \
40 CPU_SUBTYPE_SH7343 40 CPU_SUBTYPE_SH7343
41 default "0xffea0000" if CPU_SUBTYPE_SH7785 41 default "0xffeb0000" if CPU_SUBTYPE_SH7785
42 default "0xffeb0000" if CPU_SUBTYPE_SH7786 42 default "0xffeb0000" if CPU_SUBTYPE_SH7786
43 default "0xfffe8000" if CPU_SUBTYPE_SH7203 43 default "0xfffe8000" if CPU_SUBTYPE_SH7203
44 default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263 44 default "0xfffe9800" if CPU_SUBTYPE_SH7206 || CPU_SUBTYPE_SH7263
diff --git a/arch/sh/include/asm/entry-macros.S b/arch/sh/include/asm/entry-macros.S
index 3a4752a65722..1bdd93891cd7 100644
--- a/arch/sh/include/asm/entry-macros.S
+++ b/arch/sh/include/asm/entry-macros.S
@@ -31,6 +31,78 @@
31#endif 31#endif
32 .endm 32 .endm
33 33
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
637834: .long trace_hardirqs_on
647835:
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
947834: .long trace_hardirqs_off
957835:
96 .endm
97
98#else
99 .macro TRACE_IRQS_ON
100 .endm
101
102 .macro TRACE_IRQS_OFF
103 .endm
104#endif
105
34#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4) 106#if defined(CONFIG_CPU_SH2A) || defined(CONFIG_CPU_SH4)
35# define PREF(x) pref @x 107# define PREF(x) pref @x
36#else 108#else
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
56ENTRY(exception_error) 56ENTRY(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
691: .long do_exception_error 651: .long do_exception_error
70#ifdef CONFIG_TRACE_IRQFLAGS
712: .long trace_hardirqs_on
72#endif
73 66
74 .align 2 67 .align 2
75ret_from_exception: 68ret_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
82ENTRY(ret_from_irq) 70ENTRY(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
809:
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:
125ENTRY(resume_userspace) 122ENTRY(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:
1721: .long schedule 1611: .long schedule
1732: .long do_notify_resume 1622: .long do_notify_resume
1743: .long resume_userspace 1633: .long resume_userspace
175#ifdef CONFIG_TRACE_IRQFLAGS
1764: .long trace_hardirqs_on
1775: .long trace_hardirqs_off
178#endif
179 164
180 .align 2 165 .align 2
181syscall_exit_work: 166syscall_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 !
356syscall_exit: 333syscall_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
3782: .long NR_syscalls 3512: .long NR_syscalls
3793: .long sys_call_table 3523: .long sys_call_table
380#ifdef CONFIG_TRACE_IRQFLAGS
3815: .long trace_hardirqs_on
3826: .long trace_hardirqs_off
383#endif
3847: .long do_syscall_trace_enter 3537: .long do_syscall_trace_enter
3858: .long do_syscall_trace_leave 3548: .long do_syscall_trace_leave
diff --git a/arch/sh/kernel/io_trapped.c b/arch/sh/kernel/io_trapped.c
index 77dfecb64373..e27a19e1f46e 100644
--- a/arch/sh/kernel/io_trapped.c
+++ b/arch/sh/kernel/io_trapped.c
@@ -112,14 +112,15 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
112 struct trapped_io *tiop; 112 struct trapped_io *tiop;
113 struct resource *res; 113 struct resource *res;
114 int k, len; 114 int k, len;
115 unsigned long flags;
115 116
116 spin_lock_irq(&trapped_lock); 117 spin_lock_irqsave(&trapped_lock, flags);
117 list_for_each_entry(tiop, list, list) { 118 list_for_each_entry(tiop, list, list) {
118 voffs = 0; 119 voffs = 0;
119 for (k = 0; k < tiop->num_resources; k++) { 120 for (k = 0; k < tiop->num_resources; k++) {
120 res = tiop->resource + k; 121 res = tiop->resource + k;
121 if (res->start == offset) { 122 if (res->start == offset) {
122 spin_unlock_irq(&trapped_lock); 123 spin_unlock_irqrestore(&trapped_lock, flags);
123 return tiop->virt_base + voffs; 124 return tiop->virt_base + voffs;
124 } 125 }
125 126
@@ -127,7 +128,7 @@ void __iomem *match_trapped_io_handler(struct list_head *list,
127 voffs += roundup(len, PAGE_SIZE); 128 voffs += roundup(len, PAGE_SIZE);
128 } 129 }
129 } 130 }
130 spin_unlock_irq(&trapped_lock); 131 spin_unlock_irqrestore(&trapped_lock, flags);
131 return NULL; 132 return NULL;
132} 133}
133EXPORT_SYMBOL_GPL(match_trapped_io_handler); 134EXPORT_SYMBOL_GPL(match_trapped_io_handler);
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c
index 8e2feb563347..4cbb87ad070a 100644
--- a/drivers/serial/sh-sci.c
+++ b/drivers/serial/sh-sci.c
@@ -662,10 +662,11 @@ static irqreturn_t sci_rx_interrupt(int irq, void *port)
662static irqreturn_t sci_tx_interrupt(int irq, void *ptr) 662static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
663{ 663{
664 struct uart_port *port = ptr; 664 struct uart_port *port = ptr;
665 unsigned long flags;
665 666
666 spin_lock_irq(&port->lock); 667 spin_lock_irqsave(&port->lock, flags);
667 sci_transmit_chars(port); 668 sci_transmit_chars(port);
668 spin_unlock_irq(&port->lock); 669 spin_unlock_irqrestore(&port->lock, flags);
669 670
670 return IRQ_HANDLED; 671 return IRQ_HANDLED;
671} 672}