aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/spinlock.h
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2006-11-25 14:09:36 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-11-25 16:28:34 -0500
commitee3ce191e8eaa4cc15c51a28b34143b36404c4f5 (patch)
tree557c5ade9b92e91f095e4017d97ffe7afd83383f /include/linux/spinlock.h
parent5e66b0b5f187c811419ff10cfb5668c028a64d57 (diff)
[PATCH] Enforce "unsigned long flags;" when spinlocking
Make it break or warn if you pass to spin_lock_irqsave() and friends something different from "unsigned long flags;". Suprisingly large amount of these was caught by recent commit c53421b18f205c5f97c604ae55c6a921f034b0f6 and others. Idea is largely from FRV typechecking. Suggestions from Andrew Morton. All stupid typos in first version fixed. Passes allmodconfig on i386, x86_64, alpha, arm as well as my usual config. Note #1: checking with sparse is still needed, because a driver can save and pass around flags or something. So far patch is very intrusive. Note #2: techically, we should break only if sizeof(flags) < sizeof(unsigned long), however, the more pain for getting suspicious code into kernel, the better. Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/linux/spinlock.h')
-rw-r--r--include/linux/spinlock.h53
1 files changed, 44 insertions, 9 deletions
diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h
index b800d2d68b32..54ad37089c49 100644
--- a/include/linux/spinlock.h
+++ b/include/linux/spinlock.h
@@ -52,6 +52,7 @@
52#include <linux/thread_info.h> 52#include <linux/thread_info.h>
53#include <linux/kernel.h> 53#include <linux/kernel.h>
54#include <linux/stringify.h> 54#include <linux/stringify.h>
55#include <linux/irqflags.h>
55 56
56#include <asm/system.h> 57#include <asm/system.h>
57 58
@@ -183,13 +184,37 @@ do { \
183#define read_lock(lock) _read_lock(lock) 184#define read_lock(lock) _read_lock(lock)
184 185
185#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) 186#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
186#define spin_lock_irqsave(lock, flags) flags = _spin_lock_irqsave(lock) 187#define spin_lock_irqsave(lock, flags) \
187#define read_lock_irqsave(lock, flags) flags = _read_lock_irqsave(lock) 188 do { \
188#define write_lock_irqsave(lock, flags) flags = _write_lock_irqsave(lock) 189 BUILD_CHECK_IRQ_FLAGS(flags); \
190 flags = _spin_lock_irqsave(lock); \
191 } while (0)
192#define read_lock_irqsave(lock, flags) \
193 do { \
194 BUILD_CHECK_IRQ_FLAGS(flags); \
195 flags = _read_lock_irqsave(lock); \
196 } while (0)
197#define write_lock_irqsave(lock, flags) \
198 do { \
199 BUILD_CHECK_IRQ_FLAGS(flags); \
200 flags = _write_lock_irqsave(lock); \
201 } while (0)
189#else 202#else
190#define spin_lock_irqsave(lock, flags) _spin_lock_irqsave(lock, flags) 203#define spin_lock_irqsave(lock, flags) \
191#define read_lock_irqsave(lock, flags) _read_lock_irqsave(lock, flags) 204 do { \
192#define write_lock_irqsave(lock, flags) _write_lock_irqsave(lock, flags) 205 BUILD_CHECK_IRQ_FLAGS(flags); \
206 _spin_lock_irqsave(lock, flags); \
207 } while (0)
208#define read_lock_irqsave(lock, flags) \
209 do { \
210 BUILD_CHECK_IRQ_FLAGS(flags); \
211 _read_lock_irqsave(lock, flags); \
212 } while (0)
213#define write_lock_irqsave(lock, flags) \
214 do { \
215 BUILD_CHECK_IRQ_FLAGS(flags); \
216 _write_lock_irqsave(lock, flags); \
217 } while (0)
193#endif 218#endif
194 219
195#define spin_lock_irq(lock) _spin_lock_irq(lock) 220#define spin_lock_irq(lock) _spin_lock_irq(lock)
@@ -225,15 +250,24 @@ do { \
225#endif 250#endif
226 251
227#define spin_unlock_irqrestore(lock, flags) \ 252#define spin_unlock_irqrestore(lock, flags) \
228 _spin_unlock_irqrestore(lock, flags) 253 do { \
254 BUILD_CHECK_IRQ_FLAGS(flags); \
255 _spin_unlock_irqrestore(lock, flags); \
256 } while (0)
229#define spin_unlock_bh(lock) _spin_unlock_bh(lock) 257#define spin_unlock_bh(lock) _spin_unlock_bh(lock)
230 258
231#define read_unlock_irqrestore(lock, flags) \ 259#define read_unlock_irqrestore(lock, flags) \
232 _read_unlock_irqrestore(lock, flags) 260 do { \
261 BUILD_CHECK_IRQ_FLAGS(flags); \
262 _read_unlock_irqrestore(lock, flags); \
263 } while (0)
233#define read_unlock_bh(lock) _read_unlock_bh(lock) 264#define read_unlock_bh(lock) _read_unlock_bh(lock)
234 265
235#define write_unlock_irqrestore(lock, flags) \ 266#define write_unlock_irqrestore(lock, flags) \
236 _write_unlock_irqrestore(lock, flags) 267 do { \
268 BUILD_CHECK_IRQ_FLAGS(flags); \
269 _write_unlock_irqrestore(lock, flags); \
270 } while (0)
237#define write_unlock_bh(lock) _write_unlock_bh(lock) 271#define write_unlock_bh(lock) _write_unlock_bh(lock)
238 272
239#define spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock)) 273#define spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock))
@@ -247,6 +281,7 @@ do { \
247 281
248#define spin_trylock_irqsave(lock, flags) \ 282#define spin_trylock_irqsave(lock, flags) \
249({ \ 283({ \
284 BUILD_CHECK_IRQ_FLAGS(flags); \
250 local_irq_save(flags); \ 285 local_irq_save(flags); \
251 spin_trylock(lock) ? \ 286 spin_trylock(lock) ? \
252 1 : ({ local_irq_restore(flags); 0; }); \ 287 1 : ({ local_irq_restore(flags); 0; }); \