aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <rostedt@goodmis.org>2008-07-25 04:45:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-25 13:53:26 -0400
commit3f307891ce0e7b0438c432af1aacd656a092ff45 (patch)
tree603d106da47ce7d039ceb304e2c7f7ae38daf87b
parente0deaff470900a4c3222ca7139f6c9639e26a2f5 (diff)
locking: add typecheck on irqsave and friends for correct flags
There haave been several areas in the kernel where an int has been used for flags in local_irq_save() and friends instead of a long. This can cause some hard to debug problems on some architectures. This patch adds a typecheck inside the irqsave and restore functions to flag these cases. [akpm@linux-foundation.org: coding-style fixes] [akpm@linux-foundation.org: build fix] Signed-off-by: Steven Rostedt <srostedt@redhat.com> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--include/linux/irqflags.h54
-rw-r--r--include/linux/spinlock.h72
2 files changed, 95 insertions, 31 deletions
diff --git a/include/linux/irqflags.h b/include/linux/irqflags.h
index 2b1c2e58566e..74bde13224c9 100644
--- a/include/linux/irqflags.h
+++ b/include/linux/irqflags.h
@@ -11,6 +11,8 @@
11#ifndef _LINUX_TRACE_IRQFLAGS_H 11#ifndef _LINUX_TRACE_IRQFLAGS_H
12#define _LINUX_TRACE_IRQFLAGS_H 12#define _LINUX_TRACE_IRQFLAGS_H
13 13
14#include <linux/typecheck.h>
15
14#ifdef CONFIG_TRACE_IRQFLAGS 16#ifdef CONFIG_TRACE_IRQFLAGS
15 extern void trace_softirqs_on(unsigned long ip); 17 extern void trace_softirqs_on(unsigned long ip);
16 extern void trace_softirqs_off(unsigned long ip); 18 extern void trace_softirqs_off(unsigned long ip);
@@ -58,18 +60,24 @@
58 do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0) 60 do { trace_hardirqs_on(); raw_local_irq_enable(); } while (0)
59#define local_irq_disable() \ 61#define local_irq_disable() \
60 do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0) 62 do { raw_local_irq_disable(); trace_hardirqs_off(); } while (0)
61#define local_irq_save(flags) \ 63#define local_irq_save(flags) \
62 do { raw_local_irq_save(flags); trace_hardirqs_off(); } while (0) 64 do { \
65 typecheck(unsigned long, flags); \
66 raw_local_irq_save(flags); \
67 trace_hardirqs_off(); \
68 } while (0)
63 69
64#define local_irq_restore(flags) \ 70
65 do { \ 71#define local_irq_restore(flags) \
66 if (raw_irqs_disabled_flags(flags)) { \ 72 do { \
67 raw_local_irq_restore(flags); \ 73 typecheck(unsigned long, flags); \
68 trace_hardirqs_off(); \ 74 if (raw_irqs_disabled_flags(flags)) { \
69 } else { \ 75 raw_local_irq_restore(flags); \
70 trace_hardirqs_on(); \ 76 trace_hardirqs_off(); \
71 raw_local_irq_restore(flags); \ 77 } else { \
72 } \ 78 trace_hardirqs_on(); \
79 raw_local_irq_restore(flags); \
80 } \
73 } while (0) 81 } while (0)
74#else /* !CONFIG_TRACE_IRQFLAGS_SUPPORT */ 82#else /* !CONFIG_TRACE_IRQFLAGS_SUPPORT */
75/* 83/*
@@ -78,8 +86,16 @@
78 */ 86 */
79# define raw_local_irq_disable() local_irq_disable() 87# define raw_local_irq_disable() local_irq_disable()
80# define raw_local_irq_enable() local_irq_enable() 88# define raw_local_irq_enable() local_irq_enable()
81# define raw_local_irq_save(flags) local_irq_save(flags) 89# define raw_local_irq_save(flags) \
82# define raw_local_irq_restore(flags) local_irq_restore(flags) 90 do { \
91 typecheck(unsigned long, flags); \
92 local_irq_save(flags); \
93 } while (0)
94# define raw_local_irq_restore(flags) \
95 do { \
96 typecheck(unsigned long, flags); \
97 local_irq_restore(flags); \
98 } while (0)
83#endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */ 99#endif /* CONFIG_TRACE_IRQFLAGS_SUPPORT */
84 100
85#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT 101#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
@@ -89,7 +105,11 @@
89 raw_safe_halt(); \ 105 raw_safe_halt(); \
90 } while (0) 106 } while (0)
91 107
92#define local_save_flags(flags) raw_local_save_flags(flags) 108#define local_save_flags(flags) \
109 do { \
110 typecheck(unsigned long, flags); \
111 raw_local_save_flags(flags); \
112 } while (0)
93 113
94#define irqs_disabled() \ 114#define irqs_disabled() \
95({ \ 115({ \
@@ -99,7 +119,11 @@
99 raw_irqs_disabled_flags(_flags); \ 119 raw_irqs_disabled_flags(_flags); \
100}) 120})
101 121
102#define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags) 122#define irqs_disabled_flags(flags) \
123({ \
124 typecheck(unsigned long, flags); \
125 raw_irqs_disabled_flags(flags); \
126})
103#endif /* CONFIG_X86 */ 127#endif /* CONFIG_X86 */
104 128
105#endif 129#endif
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index d311a090fae7..61e5610ad165 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -46,6 +46,7 @@
46 * linux/spinlock.h: builds the final spin_*() APIs. 46 * linux/spinlock.h: builds the final spin_*() APIs.
47 */ 47 */
48 48
49#include <linux/typecheck.h>
49#include <linux/preempt.h> 50#include <linux/preempt.h>
50#include <linux/linkage.h> 51#include <linux/linkage.h>
51#include <linux/compiler.h> 52#include <linux/compiler.h>
@@ -191,23 +192,53 @@ do { \
191 192
192#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) 193#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
193 194
194#define spin_lock_irqsave(lock, flags) flags = _spin_lock_irqsave(lock) 195#define spin_lock_irqsave(lock, flags) \
195#define read_lock_irqsave(lock, flags) flags = _read_lock_irqsave(lock) 196 do { \
196#define write_lock_irqsave(lock, flags) flags = _write_lock_irqsave(lock) 197 typecheck(unsigned long, flags); \
198 flags = _spin_lock_irqsave(lock); \
199 } while (0)
200#define read_lock_irqsave(lock, flags) \
201 do { \
202 typecheck(unsigned long, flags); \
203 flags = _read_lock_irqsave(lock); \
204 } while (0)
205#define write_lock_irqsave(lock, flags) \
206 do { \
207 typecheck(unsigned long, flags); \
208 flags = _write_lock_irqsave(lock); \
209 } while (0)
197 210
198#ifdef CONFIG_DEBUG_LOCK_ALLOC 211#ifdef CONFIG_DEBUG_LOCK_ALLOC
199#define spin_lock_irqsave_nested(lock, flags, subclass) \ 212#define spin_lock_irqsave_nested(lock, flags, subclass) \
200 flags = _spin_lock_irqsave_nested(lock, subclass) 213 do { \
214 typecheck(unsigned long, flags); \
215 flags = _spin_lock_irqsave_nested(lock, subclass); \
216 } while (0)
201#else 217#else
202#define spin_lock_irqsave_nested(lock, flags, subclass) \ 218#define spin_lock_irqsave_nested(lock, flags, subclass) \
203 flags = _spin_lock_irqsave(lock) 219 do { \
220 typecheck(unsigned long, flags); \
221 flags = _spin_lock_irqsave(lock); \
222 } while (0)
204#endif 223#endif
205 224
206#else 225#else
207 226
208#define spin_lock_irqsave(lock, flags) _spin_lock_irqsave(lock, flags) 227#define spin_lock_irqsave(lock, flags) \
209#define read_lock_irqsave(lock, flags) _read_lock_irqsave(lock, flags) 228 do { \
210#define write_lock_irqsave(lock, flags) _write_lock_irqsave(lock, flags) 229 typecheck(unsigned long, flags); \
230 _spin_lock_irqsave(lock, flags); \
231 } while (0)
232#define read_lock_irqsave(lock, flags) \
233 do { \
234 typecheck(unsigned long, flags); \
235 _read_lock_irqsave(lock, flags); \
236 } while (0)
237#define write_lock_irqsave(lock, flags) \
238 do { \
239 typecheck(unsigned long, flags); \
240 _write_lock_irqsave(lock, flags); \
241 } while (0)
211#define spin_lock_irqsave_nested(lock, flags, subclass) \ 242#define spin_lock_irqsave_nested(lock, flags, subclass) \
212 spin_lock_irqsave(lock, flags) 243 spin_lock_irqsave(lock, flags)
213 244
@@ -260,16 +291,25 @@ do { \
260} while (0) 291} while (0)
261#endif 292#endif
262 293
263#define spin_unlock_irqrestore(lock, flags) \ 294#define spin_unlock_irqrestore(lock, flags) \
264 _spin_unlock_irqrestore(lock, flags) 295 do { \
296 typecheck(unsigned long, flags); \
297 _spin_unlock_irqrestore(lock, flags); \
298 } while (0)
265#define spin_unlock_bh(lock) _spin_unlock_bh(lock) 299#define spin_unlock_bh(lock) _spin_unlock_bh(lock)
266 300
267#define read_unlock_irqrestore(lock, flags) \ 301#define read_unlock_irqrestore(lock, flags) \
268 _read_unlock_irqrestore(lock, flags) 302 do { \
303 typecheck(unsigned long, flags); \
304 _read_unlock_irqrestore(lock, flags); \
305 } while (0)
269#define read_unlock_bh(lock) _read_unlock_bh(lock) 306#define read_unlock_bh(lock) _read_unlock_bh(lock)
270 307
271#define write_unlock_irqrestore(lock, flags) \ 308#define write_unlock_irqrestore(lock, flags) \
272 _write_unlock_irqrestore(lock, flags) 309 do { \
310 typecheck(unsigned long, flags); \
311 _write_unlock_irqrestore(lock, flags); \
312 } while (0)
273#define write_unlock_bh(lock) _write_unlock_bh(lock) 313#define write_unlock_bh(lock) _write_unlock_bh(lock)
274 314
275#define spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock)) 315#define spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock))