diff options
Diffstat (limited to 'include/asm-generic/bug.h')
| -rw-r--r-- | include/asm-generic/bug.h | 133 | 
1 files changed, 85 insertions, 48 deletions
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index c2c9ba032d4..630dd237223 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -3,10 +3,18 @@  #include <linux/compiler.h> +#ifdef CONFIG_GENERIC_BUG +#define BUGFLAG_WARNING		(1 << 0) +#define BUGFLAG_TAINT(taint)	(BUGFLAG_WARNING | ((taint) << 8)) +#define BUG_GET_TAINT(bug)	((bug)->flags >> 8) +#endif + +#ifndef __ASSEMBLY__ +#include <linux/kernel.h> +  #ifdef CONFIG_BUG  #ifdef CONFIG_GENERIC_BUG -#ifndef __ASSEMBLY__  struct bug_entry {  #ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS  	unsigned long	bug_addr; @@ -23,12 +31,6 @@ struct bug_entry {  #endif  	unsigned short	flags;  }; -#endif		/* __ASSEMBLY__ */ - -#define BUGFLAG_WARNING		(1 << 0) -#define BUGFLAG_TAINT(taint)	(BUGFLAG_WARNING | ((taint) << 8)) -#define BUG_GET_TAINT(bug)	((bug)->flags >> 8) -  #endif	/* CONFIG_GENERIC_BUG */  /* @@ -50,7 +52,7 @@ struct bug_entry {  #endif  #ifndef HAVE_ARCH_BUG_ON -#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while(0) +#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while (0)  #endif  /* @@ -60,15 +62,14 @@ struct bug_entry {   * to provide better diagnostics.   */  #ifndef __WARN_TAINT -#ifndef __ASSEMBLY__ -extern void warn_slowpath_fmt(const char *file, const int line, -		const char *fmt, ...) __attribute__((format(printf, 3, 4))); -extern void warn_slowpath_fmt_taint(const char *file, const int line, -				    unsigned taint, const char *fmt, ...) -	__attribute__((format(printf, 4, 5))); +extern __printf(3, 4) +void warn_slowpath_fmt(const char *file, const int line, +		       const char *fmt, ...); +extern __printf(4, 5) +void warn_slowpath_fmt_taint(const char *file, const int line, unsigned taint, +			     const char *fmt, ...);  extern void warn_slowpath_null(const char *file, const int line);  #define WANT_WARN_ON_SLOWPATH -#endif  #define __WARN()		warn_slowpath_null(__FILE__, __LINE__)  #define __WARN_printf(arg...)	warn_slowpath_fmt(__FILE__, __LINE__, arg)  #define __WARN_printf_taint(taint, arg...)				\ @@ -105,35 +106,8 @@ extern void warn_slowpath_null(const char *file, const int line);  	unlikely(__ret_warn_on);					\  }) -#else /* !CONFIG_BUG */ -#ifndef HAVE_ARCH_BUG -#define BUG() do {} while(0) -#endif - -#ifndef HAVE_ARCH_BUG_ON -#define BUG_ON(condition) do { if (condition) ; } while(0) -#endif - -#ifndef HAVE_ARCH_WARN_ON -#define WARN_ON(condition) ({						\ -	int __ret_warn_on = !!(condition);				\ -	unlikely(__ret_warn_on);					\ -}) -#endif - -#ifndef WARN -#define WARN(condition, format...) ({					\ -	int __ret_warn_on = !!(condition);				\ -	unlikely(__ret_warn_on);					\ -}) -#endif - -#define WARN_TAINT(condition, taint, format...) WARN_ON(condition) - -#endif -  #define WARN_ON_ONCE(condition)	({				\ -	static bool __warned;					\ +	static bool __section(.data.unlikely) __warned;		\  	int __ret_warn_once = !!(condition);			\  								\  	if (unlikely(__ret_warn_once))				\ @@ -143,7 +117,7 @@ extern void warn_slowpath_null(const char *file, const int line);  })  #define WARN_ONCE(condition, format...)	({			\ -	static bool __warned;					\ +	static bool __section(.data.unlikely) __warned;		\  	int __ret_warn_once = !!(condition);			\  								\  	if (unlikely(__ret_warn_once))				\ @@ -153,7 +127,7 @@ extern void warn_slowpath_null(const char *file, const int line);  })  #define WARN_TAINT_ONCE(condition, taint, format...)	({	\ -	static bool __warned;					\ +	static bool __section(.data.unlikely) __warned;		\  	int __ret_warn_once = !!(condition);			\  								\  	if (unlikely(__ret_warn_once))				\ @@ -162,13 +136,76 @@ extern void warn_slowpath_null(const char *file, const int line);  	unlikely(__ret_warn_once);				\  }) -#define WARN_ON_RATELIMIT(condition, state)			\ -		WARN_ON((condition) && __ratelimit(state)) +#else /* !CONFIG_BUG */ +#ifndef HAVE_ARCH_BUG +#define BUG() do {} while (1) +#endif + +#ifndef HAVE_ARCH_BUG_ON +#define BUG_ON(condition) do { if (condition) ; } while (0) +#endif + +#ifndef HAVE_ARCH_WARN_ON +#define WARN_ON(condition) ({						\ +	int __ret_warn_on = !!(condition);				\ +	unlikely(__ret_warn_on);					\ +}) +#endif + +#ifndef WARN +#define WARN(condition, format...) ({					\ +	int __ret_warn_on = !!(condition);				\ +	no_printk(format);						\ +	unlikely(__ret_warn_on);					\ +}) +#endif + +#define WARN_ON_ONCE(condition) WARN_ON(condition) +#define WARN_ONCE(condition, format...) WARN(condition, format) +#define WARN_TAINT(condition, taint, format...) WARN(condition, format) +#define WARN_TAINT_ONCE(condition, taint, format...) WARN(condition, format) + +#endif +/* + * WARN_ON_SMP() is for cases that the warning is either + * meaningless for !SMP or may even cause failures. + * This is usually used for cases that we have + * WARN_ON(!spin_is_locked(&lock)) checks, as spin_is_locked() + * returns 0 for uniprocessor settings. + * It can also be used with values that are only defined + * on SMP: + * + * struct foo { + *  [...] + * #ifdef CONFIG_SMP + *	int bar; + * #endif + * }; + * + * void func(struct foo *zoot) + * { + *	WARN_ON_SMP(!zoot->bar); + * + * For CONFIG_SMP, WARN_ON_SMP() should act the same as WARN_ON(), + * and should be a nop and return false for uniprocessor. + * + * if (WARN_ON_SMP(x)) returns true only when CONFIG_SMP is set + * and x is true. + */  #ifdef CONFIG_SMP  # define WARN_ON_SMP(x)			WARN_ON(x)  #else -# define WARN_ON_SMP(x)			do { } while (0) +/* + * Use of ({0;}) because WARN_ON_SMP(x) may be used either as + * a stand alone line statement or as a condition in an if () + * statement. + * A simple "0" would cause gcc to give a "statement has no effect" + * warning. + */ +# define WARN_ON_SMP(x)			({0;})  #endif +#endif /* __ASSEMBLY__ */ +  #endif  | 
