2005-04-17 05:20:36 +07:00
|
|
|
#ifndef _ASM_GENERIC_BUG_H
|
|
|
|
#define _ASM_GENERIC_BUG_H
|
|
|
|
|
|
|
|
#include <linux/compiler.h>
|
|
|
|
|
2012-06-25 15:15:31 +07:00
|
|
|
#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>
|
|
|
|
|
2005-05-01 22:59:01 +07:00
|
|
|
#ifdef CONFIG_BUG
|
[PATCH] Generic BUG implementation
This patch adds common handling for kernel BUGs, for use by architectures as
they wish. The code is derived from arch/powerpc.
The advantages of having common BUG handling are:
- consistent BUG reporting across architectures
- shared implementation of out-of-line file/line data
- implement CONFIG_DEBUG_BUGVERBOSE consistently
This means that in inline impact of BUG is just the illegal instruction
itself, which is an improvement for i386 and x86-64.
A BUG is represented in the instruction stream as an illegal instruction,
which has file/line information associated with it. This extra information is
stored in the __bug_table section in the ELF file.
When the kernel gets an illegal instruction, it first confirms it might
possibly be from a BUG (ie, in kernel mode, the right illegal instruction).
It then calls report_bug(). This searches __bug_table for a matching
instruction pointer, and if found, prints the corresponding file/line
information. If report_bug() determines that it wasn't a BUG which caused the
trap, it returns BUG_TRAP_TYPE_NONE.
Some architectures (powerpc) implement WARN using the same mechanism; if the
illegal instruction was the result of a WARN, then report_bug(Q) returns
CONFIG_DEBUG_BUGVERBOSE; otherwise it returns BUG_TRAP_TYPE_BUG.
lib/bug.c keeps a list of loaded modules which can be searched for __bug_table
entries. The architecture must call
module_bug_finalize()/module_bug_cleanup() from its corresponding
module_finalize/cleanup functions.
Unsetting CONFIG_DEBUG_BUGVERBOSE will reduce the kernel size by some amount.
At the very least, filename and line information will not be recorded for each
but, but architectures may decide to store no extra information per BUG at
all.
Unfortunately, gcc doesn't have a general way to mark an asm() as noreturn, so
architectures will generally have to include an infinite loop (or similar) in
the BUG code, so that gcc knows execution won't continue beyond that point.
gcc does have a __builtin_trap() operator which may be useful to achieve the
same effect, unfortunately it cannot be used to actually implement the BUG
itself, because there's no way to get the instruction's address for use in
generating the __bug_table entry.
[randy.dunlap@oracle.com: Handle BUG=n, GENERIC_BUG=n to prevent build errors]
[bunk@stusta.de: include/linux/bug.h must always #include <linux/module.h]
Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Andi Kleen <ak@muc.de>
Cc: Hugh Dickens <hugh@veritas.com>
Cc: Michael Ellerman <michael@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-08 17:36:19 +07:00
|
|
|
|
|
|
|
#ifdef CONFIG_GENERIC_BUG
|
|
|
|
struct bug_entry {
|
2008-12-16 18:40:27 +07:00
|
|
|
#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
|
[PATCH] Generic BUG implementation
This patch adds common handling for kernel BUGs, for use by architectures as
they wish. The code is derived from arch/powerpc.
The advantages of having common BUG handling are:
- consistent BUG reporting across architectures
- shared implementation of out-of-line file/line data
- implement CONFIG_DEBUG_BUGVERBOSE consistently
This means that in inline impact of BUG is just the illegal instruction
itself, which is an improvement for i386 and x86-64.
A BUG is represented in the instruction stream as an illegal instruction,
which has file/line information associated with it. This extra information is
stored in the __bug_table section in the ELF file.
When the kernel gets an illegal instruction, it first confirms it might
possibly be from a BUG (ie, in kernel mode, the right illegal instruction).
It then calls report_bug(). This searches __bug_table for a matching
instruction pointer, and if found, prints the corresponding file/line
information. If report_bug() determines that it wasn't a BUG which caused the
trap, it returns BUG_TRAP_TYPE_NONE.
Some architectures (powerpc) implement WARN using the same mechanism; if the
illegal instruction was the result of a WARN, then report_bug(Q) returns
CONFIG_DEBUG_BUGVERBOSE; otherwise it returns BUG_TRAP_TYPE_BUG.
lib/bug.c keeps a list of loaded modules which can be searched for __bug_table
entries. The architecture must call
module_bug_finalize()/module_bug_cleanup() from its corresponding
module_finalize/cleanup functions.
Unsetting CONFIG_DEBUG_BUGVERBOSE will reduce the kernel size by some amount.
At the very least, filename and line information will not be recorded for each
but, but architectures may decide to store no extra information per BUG at
all.
Unfortunately, gcc doesn't have a general way to mark an asm() as noreturn, so
architectures will generally have to include an infinite loop (or similar) in
the BUG code, so that gcc knows execution won't continue beyond that point.
gcc does have a __builtin_trap() operator which may be useful to achieve the
same effect, unfortunately it cannot be used to actually implement the BUG
itself, because there's no way to get the instruction's address for use in
generating the __bug_table entry.
[randy.dunlap@oracle.com: Handle BUG=n, GENERIC_BUG=n to prevent build errors]
[bunk@stusta.de: include/linux/bug.h must always #include <linux/module.h]
Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Andi Kleen <ak@muc.de>
Cc: Hugh Dickens <hugh@veritas.com>
Cc: Michael Ellerman <michael@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-08 17:36:19 +07:00
|
|
|
unsigned long bug_addr;
|
2008-12-16 18:40:27 +07:00
|
|
|
#else
|
|
|
|
signed int bug_addr_disp;
|
|
|
|
#endif
|
[PATCH] Generic BUG implementation
This patch adds common handling for kernel BUGs, for use by architectures as
they wish. The code is derived from arch/powerpc.
The advantages of having common BUG handling are:
- consistent BUG reporting across architectures
- shared implementation of out-of-line file/line data
- implement CONFIG_DEBUG_BUGVERBOSE consistently
This means that in inline impact of BUG is just the illegal instruction
itself, which is an improvement for i386 and x86-64.
A BUG is represented in the instruction stream as an illegal instruction,
which has file/line information associated with it. This extra information is
stored in the __bug_table section in the ELF file.
When the kernel gets an illegal instruction, it first confirms it might
possibly be from a BUG (ie, in kernel mode, the right illegal instruction).
It then calls report_bug(). This searches __bug_table for a matching
instruction pointer, and if found, prints the corresponding file/line
information. If report_bug() determines that it wasn't a BUG which caused the
trap, it returns BUG_TRAP_TYPE_NONE.
Some architectures (powerpc) implement WARN using the same mechanism; if the
illegal instruction was the result of a WARN, then report_bug(Q) returns
CONFIG_DEBUG_BUGVERBOSE; otherwise it returns BUG_TRAP_TYPE_BUG.
lib/bug.c keeps a list of loaded modules which can be searched for __bug_table
entries. The architecture must call
module_bug_finalize()/module_bug_cleanup() from its corresponding
module_finalize/cleanup functions.
Unsetting CONFIG_DEBUG_BUGVERBOSE will reduce the kernel size by some amount.
At the very least, filename and line information will not be recorded for each
but, but architectures may decide to store no extra information per BUG at
all.
Unfortunately, gcc doesn't have a general way to mark an asm() as noreturn, so
architectures will generally have to include an infinite loop (or similar) in
the BUG code, so that gcc knows execution won't continue beyond that point.
gcc does have a __builtin_trap() operator which may be useful to achieve the
same effect, unfortunately it cannot be used to actually implement the BUG
itself, because there's no way to get the instruction's address for use in
generating the __bug_table entry.
[randy.dunlap@oracle.com: Handle BUG=n, GENERIC_BUG=n to prevent build errors]
[bunk@stusta.de: include/linux/bug.h must always #include <linux/module.h]
Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Andi Kleen <ak@muc.de>
Cc: Hugh Dickens <hugh@veritas.com>
Cc: Michael Ellerman <michael@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-08 17:36:19 +07:00
|
|
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
2008-12-16 18:40:27 +07:00
|
|
|
#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
|
[PATCH] Generic BUG implementation
This patch adds common handling for kernel BUGs, for use by architectures as
they wish. The code is derived from arch/powerpc.
The advantages of having common BUG handling are:
- consistent BUG reporting across architectures
- shared implementation of out-of-line file/line data
- implement CONFIG_DEBUG_BUGVERBOSE consistently
This means that in inline impact of BUG is just the illegal instruction
itself, which is an improvement for i386 and x86-64.
A BUG is represented in the instruction stream as an illegal instruction,
which has file/line information associated with it. This extra information is
stored in the __bug_table section in the ELF file.
When the kernel gets an illegal instruction, it first confirms it might
possibly be from a BUG (ie, in kernel mode, the right illegal instruction).
It then calls report_bug(). This searches __bug_table for a matching
instruction pointer, and if found, prints the corresponding file/line
information. If report_bug() determines that it wasn't a BUG which caused the
trap, it returns BUG_TRAP_TYPE_NONE.
Some architectures (powerpc) implement WARN using the same mechanism; if the
illegal instruction was the result of a WARN, then report_bug(Q) returns
CONFIG_DEBUG_BUGVERBOSE; otherwise it returns BUG_TRAP_TYPE_BUG.
lib/bug.c keeps a list of loaded modules which can be searched for __bug_table
entries. The architecture must call
module_bug_finalize()/module_bug_cleanup() from its corresponding
module_finalize/cleanup functions.
Unsetting CONFIG_DEBUG_BUGVERBOSE will reduce the kernel size by some amount.
At the very least, filename and line information will not be recorded for each
but, but architectures may decide to store no extra information per BUG at
all.
Unfortunately, gcc doesn't have a general way to mark an asm() as noreturn, so
architectures will generally have to include an infinite loop (or similar) in
the BUG code, so that gcc knows execution won't continue beyond that point.
gcc does have a __builtin_trap() operator which may be useful to achieve the
same effect, unfortunately it cannot be used to actually implement the BUG
itself, because there's no way to get the instruction's address for use in
generating the __bug_table entry.
[randy.dunlap@oracle.com: Handle BUG=n, GENERIC_BUG=n to prevent build errors]
[bunk@stusta.de: include/linux/bug.h must always #include <linux/module.h]
Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Andi Kleen <ak@muc.de>
Cc: Hugh Dickens <hugh@veritas.com>
Cc: Michael Ellerman <michael@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-08 17:36:19 +07:00
|
|
|
const char *file;
|
2008-12-16 18:40:27 +07:00
|
|
|
#else
|
|
|
|
signed int file_disp;
|
|
|
|
#endif
|
[PATCH] Generic BUG implementation
This patch adds common handling for kernel BUGs, for use by architectures as
they wish. The code is derived from arch/powerpc.
The advantages of having common BUG handling are:
- consistent BUG reporting across architectures
- shared implementation of out-of-line file/line data
- implement CONFIG_DEBUG_BUGVERBOSE consistently
This means that in inline impact of BUG is just the illegal instruction
itself, which is an improvement for i386 and x86-64.
A BUG is represented in the instruction stream as an illegal instruction,
which has file/line information associated with it. This extra information is
stored in the __bug_table section in the ELF file.
When the kernel gets an illegal instruction, it first confirms it might
possibly be from a BUG (ie, in kernel mode, the right illegal instruction).
It then calls report_bug(). This searches __bug_table for a matching
instruction pointer, and if found, prints the corresponding file/line
information. If report_bug() determines that it wasn't a BUG which caused the
trap, it returns BUG_TRAP_TYPE_NONE.
Some architectures (powerpc) implement WARN using the same mechanism; if the
illegal instruction was the result of a WARN, then report_bug(Q) returns
CONFIG_DEBUG_BUGVERBOSE; otherwise it returns BUG_TRAP_TYPE_BUG.
lib/bug.c keeps a list of loaded modules which can be searched for __bug_table
entries. The architecture must call
module_bug_finalize()/module_bug_cleanup() from its corresponding
module_finalize/cleanup functions.
Unsetting CONFIG_DEBUG_BUGVERBOSE will reduce the kernel size by some amount.
At the very least, filename and line information will not be recorded for each
but, but architectures may decide to store no extra information per BUG at
all.
Unfortunately, gcc doesn't have a general way to mark an asm() as noreturn, so
architectures will generally have to include an infinite loop (or similar) in
the BUG code, so that gcc knows execution won't continue beyond that point.
gcc does have a __builtin_trap() operator which may be useful to achieve the
same effect, unfortunately it cannot be used to actually implement the BUG
itself, because there's no way to get the instruction's address for use in
generating the __bug_table entry.
[randy.dunlap@oracle.com: Handle BUG=n, GENERIC_BUG=n to prevent build errors]
[bunk@stusta.de: include/linux/bug.h must always #include <linux/module.h]
Signed-off-by: Jeremy Fitzhardinge <jeremy@goop.org>
Cc: Andi Kleen <ak@muc.de>
Cc: Hugh Dickens <hugh@veritas.com>
Cc: Michael Ellerman <michael@ellerman.id.au>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-12-08 17:36:19 +07:00
|
|
|
unsigned short line;
|
|
|
|
#endif
|
|
|
|
unsigned short flags;
|
|
|
|
};
|
|
|
|
#endif /* CONFIG_GENERIC_BUG */
|
|
|
|
|
2009-01-07 05:41:01 +07:00
|
|
|
/*
|
|
|
|
* Don't use BUG() or BUG_ON() unless there's really no way out; one
|
|
|
|
* example might be detecting data structure corruption in the middle
|
|
|
|
* of an operation that can't be backed out of. If the (sub)system
|
|
|
|
* can somehow continue operating, perhaps with reduced functionality,
|
|
|
|
* it's probably not BUG-worthy.
|
|
|
|
*
|
|
|
|
* If you're tempted to BUG(), think again: is completely giving up
|
|
|
|
* really the *only* solution? There are usually better options, where
|
|
|
|
* users don't need to reboot ASAP and can mostly shut down cleanly.
|
|
|
|
*/
|
2005-04-17 05:20:36 +07:00
|
|
|
#ifndef HAVE_ARCH_BUG
|
|
|
|
#define BUG() do { \
|
2008-10-16 12:01:24 +07:00
|
|
|
printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
|
2005-04-17 05:20:36 +07:00
|
|
|
panic("BUG!"); \
|
|
|
|
} while (0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef HAVE_ARCH_BUG_ON
|
2014-04-08 05:39:11 +07:00
|
|
|
#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while (0)
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
|
|
|
|
2009-01-07 05:41:01 +07:00
|
|
|
/*
|
|
|
|
* WARN(), WARN_ON(), WARN_ON_ONCE, and so on can be used to report
|
|
|
|
* significant issues that need prompt attention if they should ever
|
|
|
|
* appear at runtime. Use the versions with printk format strings
|
|
|
|
* to provide better diagnostics.
|
|
|
|
*/
|
2010-04-04 01:34:56 +07:00
|
|
|
#ifndef __WARN_TAINT
|
2011-11-01 07:11:33 +07:00
|
|
|
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, ...);
|
2009-05-07 06:02:53 +07:00
|
|
|
extern void warn_slowpath_null(const char *file, const int line);
|
2008-01-30 19:32:50 +07:00
|
|
|
#define WANT_WARN_ON_SLOWPATH
|
2009-05-07 06:02:53 +07:00
|
|
|
#define __WARN() warn_slowpath_null(__FILE__, __LINE__)
|
|
|
|
#define __WARN_printf(arg...) warn_slowpath_fmt(__FILE__, __LINE__, arg)
|
2010-04-04 01:34:56 +07:00
|
|
|
#define __WARN_printf_taint(taint, arg...) \
|
|
|
|
warn_slowpath_fmt_taint(__FILE__, __LINE__, taint, arg)
|
2008-07-25 15:45:53 +07:00
|
|
|
#else
|
2010-04-04 01:34:56 +07:00
|
|
|
#define __WARN() __WARN_TAINT(TAINT_WARN)
|
2008-11-28 23:56:14 +07:00
|
|
|
#define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0)
|
2010-04-04 01:34:56 +07:00
|
|
|
#define __WARN_printf_taint(taint, arg...) \
|
|
|
|
do { printk(arg); __WARN_TAINT(taint); } while (0)
|
2008-01-30 19:32:50 +07:00
|
|
|
#endif
|
|
|
|
|
2016-03-18 04:23:04 +07:00
|
|
|
/* used internally by panic.c */
|
|
|
|
struct warn_args;
|
|
|
|
|
|
|
|
void __warn(const char *file, int line, void *caller, unsigned taint,
|
|
|
|
struct pt_regs *regs, struct warn_args *args);
|
|
|
|
|
2008-01-30 19:32:50 +07:00
|
|
|
#ifndef WARN_ON
|
2006-09-29 15:59:06 +07:00
|
|
|
#define WARN_ON(condition) ({ \
|
2007-08-01 11:12:07 +07:00
|
|
|
int __ret_warn_on = !!(condition); \
|
2008-01-30 19:32:50 +07:00
|
|
|
if (unlikely(__ret_warn_on)) \
|
|
|
|
__WARN(); \
|
2006-09-29 15:59:06 +07:00
|
|
|
unlikely(__ret_warn_on); \
|
|
|
|
})
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
|
|
|
|
2008-07-25 15:45:53 +07:00
|
|
|
#ifndef WARN
|
|
|
|
#define WARN(condition, format...) ({ \
|
|
|
|
int __ret_warn_on = !!(condition); \
|
|
|
|
if (unlikely(__ret_warn_on)) \
|
|
|
|
__WARN_printf(format); \
|
|
|
|
unlikely(__ret_warn_on); \
|
|
|
|
})
|
|
|
|
#endif
|
|
|
|
|
2010-04-04 01:34:56 +07:00
|
|
|
#define WARN_TAINT(condition, taint, format...) ({ \
|
|
|
|
int __ret_warn_on = !!(condition); \
|
|
|
|
if (unlikely(__ret_warn_on)) \
|
|
|
|
__WARN_printf_taint(taint, format); \
|
|
|
|
unlikely(__ret_warn_on); \
|
|
|
|
})
|
|
|
|
|
2006-10-06 14:43:49 +07:00
|
|
|
#define WARN_ON_ONCE(condition) ({ \
|
2012-03-24 05:01:52 +07:00
|
|
|
static bool __section(.data.unlikely) __warned; \
|
2007-08-01 11:12:07 +07:00
|
|
|
int __ret_warn_once = !!(condition); \
|
2006-10-06 14:43:49 +07:00
|
|
|
\
|
2016-03-18 04:21:12 +07:00
|
|
|
if (unlikely(__ret_warn_once && !__warned)) { \
|
|
|
|
__warned = true; \
|
|
|
|
WARN_ON(1); \
|
|
|
|
} \
|
2006-10-06 14:43:49 +07:00
|
|
|
unlikely(__ret_warn_once); \
|
2006-06-25 19:48:09 +07:00
|
|
|
})
|
|
|
|
|
2008-09-16 06:43:18 +07:00
|
|
|
#define WARN_ONCE(condition, format...) ({ \
|
2012-03-24 05:01:52 +07:00
|
|
|
static bool __section(.data.unlikely) __warned; \
|
2008-09-16 06:43:18 +07:00
|
|
|
int __ret_warn_once = !!(condition); \
|
|
|
|
\
|
2016-03-18 04:21:12 +07:00
|
|
|
if (unlikely(__ret_warn_once && !__warned)) { \
|
|
|
|
__warned = true; \
|
|
|
|
WARN(1, format); \
|
|
|
|
} \
|
2008-09-16 06:43:18 +07:00
|
|
|
unlikely(__ret_warn_once); \
|
|
|
|
})
|
|
|
|
|
2010-04-04 01:34:56 +07:00
|
|
|
#define WARN_TAINT_ONCE(condition, taint, format...) ({ \
|
2012-03-24 05:01:52 +07:00
|
|
|
static bool __section(.data.unlikely) __warned; \
|
2010-04-04 01:34:56 +07:00
|
|
|
int __ret_warn_once = !!(condition); \
|
|
|
|
\
|
2016-03-18 04:21:12 +07:00
|
|
|
if (unlikely(__ret_warn_once && !__warned)) { \
|
|
|
|
__warned = true; \
|
|
|
|
WARN_TAINT(1, taint, format); \
|
|
|
|
} \
|
2010-04-04 01:34:56 +07:00
|
|
|
unlikely(__ret_warn_once); \
|
|
|
|
})
|
|
|
|
|
2014-04-08 05:39:10 +07:00
|
|
|
#else /* !CONFIG_BUG */
|
|
|
|
#ifndef HAVE_ARCH_BUG
|
2014-04-08 05:39:13 +07:00
|
|
|
#define BUG() do {} while (1)
|
2014-04-08 05:39:10 +07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef HAVE_ARCH_BUG_ON
|
asm-generic: default BUG_ON(x) to if(x)BUG()
When CONFIG_BUG is disabled, BUG_ON() will only evaluate the condition,
but will not actually stop the current thread. GCC warns about a couple
of BUG_ON() users where this actually leads to further undefined
behavior:
include/linux/ceph/osdmap.h: In function 'ceph_can_shift_osds':
include/linux/ceph/osdmap.h:54:1: warning: control reaches end of non-void function
fs/ext4/inode.c: In function 'ext4_map_blocks':
fs/ext4/inode.c:548:5: warning: 'retval' may be used uninitialized in this function
drivers/mfd/db8500-prcmu.c: In function 'prcmu_config_clkout':
drivers/mfd/db8500-prcmu.c:762:10: warning: 'div_mask' may be used uninitialized in this function
drivers/mfd/db8500-prcmu.c:769:13: warning: 'mask' may be used uninitialized in this function
drivers/mfd/db8500-prcmu.c:757:7: warning: 'bits' may be used uninitialized in this function
drivers/tty/serial/8250/8250_core.c: In function 'univ8250_release_irq':
drivers/tty/serial/8250/8250_core.c:252:18: warning: 'i' may be used uninitialized in this function
drivers/tty/serial/8250/8250_core.c:235:19: note: 'i' was declared here
There is an obvious conflict of interest here: on the one hand, someone
who disables CONFIG_BUG() will want the kernel to be as small as possible
and doesn't care about printing error messages to a console that nobody
looks at. On the other hand, running into a BUG_ON() condition means that
something has gone wrong, and we probably want to also stop doing things
that might cause data corruption.
This patch picks the second choice, and changes the NOP to BUG(), which
normally stops the execution of the current thread in some form (endless
loop or a trap). This follows the logic we applied in a4b5d580e078 ("bug:
Make BUG() always stop the machine").
For ARM multi_v7_defconfig, the size slightly increases:
section CONFIG_BUG=y CONFIG_BUG=n CONFIG_BUG=n+patch
.text 8320248 | 8180944 | 8207688
.rodata 3633720 | 3567144 | 3570648
__bug_table 32508 | --- | ---
__modver 692 | 1584 | 2176
.init.text 558132 | 548300 | 550088
.exit.text 12380 | 12256 | 12380
.data 1016672 | 1016064 | 1016128
Total 14622556 | 14374510 | 14407326
So instead of saving 1.70% of the total image size, we only save 1.48%
by turning off CONFIG_BUG, but in return we can ensure that we don't run
into cases of uninitialized variable or return code uses when something
bad happens. Aside from that, we significantly reduce the number of
warnings in randconfig builds, which makes it easier to fix the warnings
about other problems.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2015-11-21 06:27:26 +07:00
|
|
|
#define BUG_ON(condition) do { if (condition) BUG(); } while (0)
|
2014-04-08 05:39:10 +07:00
|
|
|
#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); \
|
2014-04-08 05:39:12 +07:00
|
|
|
no_printk(format); \
|
2014-04-08 05:39:10 +07:00
|
|
|
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
|
|
|
|
|
2011-03-18 02:21:06 +07:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2006-06-27 16:54:50 +07:00
|
|
|
#ifdef CONFIG_SMP
|
|
|
|
# define WARN_ON_SMP(x) WARN_ON(x)
|
|
|
|
#else
|
2011-03-26 03:21:06 +07:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
2011-03-18 02:21:06 +07:00
|
|
|
# define WARN_ON_SMP(x) ({0;})
|
2006-06-27 16:54:50 +07:00
|
|
|
#endif
|
|
|
|
|
2012-06-18 11:54:17 +07:00
|
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|