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>
This commit is contained in:
Steven Rostedt 2008-07-25 01:45:25 -07:00 committed by Linus Torvalds
commit 3f307891ce
2 changed files with 95 additions and 31 deletions

View file

@ -46,6 +46,7 @@
* linux/spinlock.h: builds the final spin_*() APIs.
*/
#include <linux/typecheck.h>
#include <linux/preempt.h>
#include <linux/linkage.h>
#include <linux/compiler.h>
@ -191,23 +192,53 @@ do { \
#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
#define spin_lock_irqsave(lock, flags) flags = _spin_lock_irqsave(lock)
#define read_lock_irqsave(lock, flags) flags = _read_lock_irqsave(lock)
#define write_lock_irqsave(lock, flags) flags = _write_lock_irqsave(lock)
#define spin_lock_irqsave(lock, flags) \
do { \
typecheck(unsigned long, flags); \
flags = _spin_lock_irqsave(lock); \
} while (0)
#define read_lock_irqsave(lock, flags) \
do { \
typecheck(unsigned long, flags); \
flags = _read_lock_irqsave(lock); \
} while (0)
#define write_lock_irqsave(lock, flags) \
do { \
typecheck(unsigned long, flags); \
flags = _write_lock_irqsave(lock); \
} while (0)
#ifdef CONFIG_DEBUG_LOCK_ALLOC
#define spin_lock_irqsave_nested(lock, flags, subclass) \
flags = _spin_lock_irqsave_nested(lock, subclass)
#define spin_lock_irqsave_nested(lock, flags, subclass) \
do { \
typecheck(unsigned long, flags); \
flags = _spin_lock_irqsave_nested(lock, subclass); \
} while (0)
#else
#define spin_lock_irqsave_nested(lock, flags, subclass) \
flags = _spin_lock_irqsave(lock)
#define spin_lock_irqsave_nested(lock, flags, subclass) \
do { \
typecheck(unsigned long, flags); \
flags = _spin_lock_irqsave(lock); \
} while (0)
#endif
#else
#define spin_lock_irqsave(lock, flags) _spin_lock_irqsave(lock, flags)
#define read_lock_irqsave(lock, flags) _read_lock_irqsave(lock, flags)
#define write_lock_irqsave(lock, flags) _write_lock_irqsave(lock, flags)
#define spin_lock_irqsave(lock, flags) \
do { \
typecheck(unsigned long, flags); \
_spin_lock_irqsave(lock, flags); \
} while (0)
#define read_lock_irqsave(lock, flags) \
do { \
typecheck(unsigned long, flags); \
_read_lock_irqsave(lock, flags); \
} while (0)
#define write_lock_irqsave(lock, flags) \
do { \
typecheck(unsigned long, flags); \
_write_lock_irqsave(lock, flags); \
} while (0)
#define spin_lock_irqsave_nested(lock, flags, subclass) \
spin_lock_irqsave(lock, flags)
@ -260,16 +291,25 @@ do { \
} while (0)
#endif
#define spin_unlock_irqrestore(lock, flags) \
_spin_unlock_irqrestore(lock, flags)
#define spin_unlock_irqrestore(lock, flags) \
do { \
typecheck(unsigned long, flags); \
_spin_unlock_irqrestore(lock, flags); \
} while (0)
#define spin_unlock_bh(lock) _spin_unlock_bh(lock)
#define read_unlock_irqrestore(lock, flags) \
_read_unlock_irqrestore(lock, flags)
#define read_unlock_irqrestore(lock, flags) \
do { \
typecheck(unsigned long, flags); \
_read_unlock_irqrestore(lock, flags); \
} while (0)
#define read_unlock_bh(lock) _read_unlock_bh(lock)
#define write_unlock_irqrestore(lock, flags) \
_write_unlock_irqrestore(lock, flags)
#define write_unlock_irqrestore(lock, flags) \
do { \
typecheck(unsigned long, flags); \
_write_unlock_irqrestore(lock, flags); \
} while (0)
#define write_unlock_bh(lock) _write_unlock_bh(lock)
#define spin_trylock_bh(lock) __cond_lock(lock, _spin_trylock_bh(lock))