blob: 0e41ade43796efa8575ddae7e27cb5ca192da659 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001#ifndef _ASM_GENERIC_BUG_H
2#define _ASM_GENERIC_BUG_H
3
4#include <linux/compiler.h>
5
6#ifndef __ASSEMBLY__
7extern void __WARN_ON(const char *func, const char *file, const int line);
8#endif /* __ASSEMBLY__ */
9
10#ifdef CONFIG_BUG
11
12#ifdef CONFIG_GENERIC_BUG
13#ifndef __ASSEMBLY__
14struct bug_entry {
15#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
16 unsigned long bug_addr;
17#else
18 signed int bug_addr_disp;
19#endif
20#ifdef CONFIG_DEBUG_BUGVERBOSE
21#ifndef CONFIG_GENERIC_BUG_RELATIVE_POINTERS
22 const char *file;
23#else
24 signed int file_disp;
25#endif
26 unsigned short line;
27#endif
28 unsigned short flags;
29};
30#endif /* __ASSEMBLY__ */
31
32#define BUGFLAG_WARNING (1 << 0)
33#define BUGFLAG_TAINT(taint) (BUGFLAG_WARNING | ((taint) << 8))
34#define BUG_GET_TAINT(bug) ((bug)->flags >> 8)
35
36#endif /* CONFIG_GENERIC_BUG */
37
38/*
39 * Don't use BUG() or BUG_ON() unless there's really no way out; one
40 * example might be detecting data structure corruption in the middle
41 * of an operation that can't be backed out of. If the (sub)system
42 * can somehow continue operating, perhaps with reduced functionality,
43 * it's probably not BUG-worthy.
44 *
45 * If you're tempted to BUG(), think again: is completely giving up
46 * really the *only* solution? There are usually better options, where
47 * users don't need to reboot ASAP and can mostly shut down cleanly.
48 */
49#ifndef HAVE_ARCH_BUG
50#define BUG() do { \
51 printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); \
52 panic("BUG!"); \
53} while (0)
54#endif
55
56#ifndef HAVE_ARCH_BUG_ON
57#define BUG_ON(condition) do { if (unlikely(condition)) BUG(); } while(0)
58#endif
59
60/*
61 * WARN(), WARN_ON(), WARN_ON_ONCE, and so on can be used to report
62 * significant issues that need prompt attention if they should ever
63 * appear at runtime. Use the versions with printk format strings
64 * to provide better diagnostics.
65 */
66#ifndef __WARN_TAINT
67#ifndef __ASSEMBLY__
68extern __printf(3, 4)
69void warn_slowpath_fmt(const char *file, const int line,
70 const char *fmt, ...);
71extern __printf(4, 5)
72void warn_slowpath_fmt_taint(const char *file, const int line, unsigned taint,
73 const char *fmt, ...);
74extern void warn_slowpath_null(const char *file, const int line);
75#define WANT_WARN_ON_SLOWPATH
76#endif
77#define __WARN() warn_slowpath_null(__FILE__, __LINE__)
78#define __WARN_printf(arg...) warn_slowpath_fmt(__FILE__, __LINE__, arg)
79#define __WARN_printf_taint(taint, arg...) \
80 warn_slowpath_fmt_taint(__FILE__, __LINE__, taint, arg)
81#else
82#define __WARN() __WARN_TAINT(TAINT_WARN)
83#define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0)
84#define __WARN_printf_taint(taint, arg...) \
85 do { printk(arg); __WARN_TAINT(taint); } while (0)
86#endif
87
88#ifndef WARN_ON
89#define WARN_ON(condition) ({ \
90 int __ret_warn_on = !!(condition); \
91 if (unlikely(__ret_warn_on)) \
92 __WARN(); \
93 unlikely(__ret_warn_on); \
94})
95#endif
96
97#ifndef WARN
98#define WARN(condition, format...) ({ \
99 int __ret_warn_on = !!(condition); \
100 if (unlikely(__ret_warn_on)) \
101 __WARN_printf(format); \
102 unlikely(__ret_warn_on); \
103})
104#endif
105
106#define WARN_TAINT(condition, taint, format...) ({ \
107 int __ret_warn_on = !!(condition); \
108 if (unlikely(__ret_warn_on)) \
109 __WARN_printf_taint(taint, format); \
110 unlikely(__ret_warn_on); \
111})
112
113#else /* !CONFIG_BUG */
114#ifndef HAVE_ARCH_BUG
115#define BUG() do {} while(0)
116#endif
117
118#ifndef HAVE_ARCH_BUG_ON
119#define BUG_ON(condition) do { if (condition) ; } while(0)
120#endif
121
122#ifndef HAVE_ARCH_WARN_ON
123#define WARN_ON(condition) ({ \
124 int __ret_warn_on = !!(condition); \
125 unlikely(__ret_warn_on); \
126})
127#endif
128
129#ifndef WARN
130#define WARN(condition, format...) ({ \
131 int __ret_warn_on = !!(condition); \
132 unlikely(__ret_warn_on); \
133})
134#endif
135
136#define WARN_TAINT(condition, taint, format...) WARN_ON(condition)
137
138#endif
139
140#define WARN_ON_ONCE(condition) ({ \
141 static bool __section(.data.unlikely) __warned; \
142 int __ret_warn_once = !!(condition); \
143 \
144 if (unlikely(__ret_warn_once)) \
145 if (WARN_ON(!__warned)) \
146 __warned = true; \
147 unlikely(__ret_warn_once); \
148})
149
150#define WARN_ONCE(condition, format...) ({ \
151 static bool __section(.data.unlikely) __warned; \
152 int __ret_warn_once = !!(condition); \
153 \
154 if (unlikely(__ret_warn_once)) \
155 if (WARN(!__warned, format)) \
156 __warned = true; \
157 unlikely(__ret_warn_once); \
158})
159
160#define WARN_TAINT_ONCE(condition, taint, format...) ({ \
161 static bool __section(.data.unlikely) __warned; \
162 int __ret_warn_once = !!(condition); \
163 \
164 if (unlikely(__ret_warn_once)) \
165 if (WARN_TAINT(!__warned, taint, format)) \
166 __warned = true; \
167 unlikely(__ret_warn_once); \
168})
169
170/*
171 * WARN_ON_SMP() is for cases that the warning is either
172 * meaningless for !SMP or may even cause failures.
173 * This is usually used for cases that we have
174 * WARN_ON(!spin_is_locked(&lock)) checks, as spin_is_locked()
175 * returns 0 for uniprocessor settings.
176 * It can also be used with values that are only defined
177 * on SMP:
178 *
179 * struct foo {
180 * [...]
181 * #ifdef CONFIG_SMP
182 * int bar;
183 * #endif
184 * };
185 *
186 * void func(struct foo *zoot)
187 * {
188 * WARN_ON_SMP(!zoot->bar);
189 *
190 * For CONFIG_SMP, WARN_ON_SMP() should act the same as WARN_ON(),
191 * and should be a nop and return false for uniprocessor.
192 *
193 * if (WARN_ON_SMP(x)) returns true only when CONFIG_SMP is set
194 * and x is true.
195 */
196#ifdef CONFIG_SMP
197# define WARN_ON_SMP(x) WARN_ON(x)
198#else
199/*
200 * Use of ({0;}) because WARN_ON_SMP(x) may be used either as
201 * a stand alone line statement or as a condition in an if ()
202 * statement.
203 * A simple "0" would cause gcc to give a "statement has no effect"
204 * warning.
205 */
206# define WARN_ON_SMP(x) ({0;})
207#endif
208
209#ifdef CONFIG_PREEMPT_RT_BASE
210# define BUG_ON_RT(c) BUG_ON(c)
211# define BUG_ON_NONRT(c) do { } while (0)
212# define WARN_ON_RT(condition) WARN_ON(condition)
213# define WARN_ON_NONRT(condition) do { } while (0)
214# define WARN_ON_ONCE_NONRT(condition) do { } while (0)
215#else
216# define BUG_ON_RT(c) do { } while (0)
217# define BUG_ON_NONRT(c) BUG_ON(c)
218# define WARN_ON_RT(condition) do { } while (0)
219# define WARN_ON_NONRT(condition) WARN_ON(condition)
220# define WARN_ON_ONCE_NONRT(condition) WARN_ON_ONCE(condition)
221#endif
222
223#endif