]> git.proxmox.com Git - mirror_zfs.git/blob - include/sys/debug.h
- Properly fix the debug support for all the ASSERT's, VERIFIES, etc can be
[mirror_zfs.git] / include / sys / debug.h
1 #ifndef _SPL_DEBUG_H
2 #define _SPL_DEBUG_H
3
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7
8 #include <linux/sched.h> /* THREAD_SIZE */
9 #include <linux/proc_fs.h>
10
11 extern unsigned long spl_debug_mask;
12 extern unsigned long spl_debug_subsys;
13
14 #define S_UNDEFINED 0x00000001
15 #define S_ATOMIC 0x00000002
16 #define S_KOBJ 0x00000004
17 #define S_VNODE 0x00000008
18 #define S_TIME 0x00000010
19 #define S_RWLOCK 0x00000020
20 #define S_THREAD 0x00000040
21 #define S_CONDVAR 0x00000080
22 #define S_MUTEX 0x00000100
23 #define S_RNG 0x00000200
24 #define S_TASKQ 0x00000400
25 #define S_KMEM 0x00000800
26 #define S_DEBUG 0x00001000
27 #define S_GENERIC 0x00002000
28 #define S_PROC 0x00004000
29 #define S_MODULE 0x00008000
30
31 #define D_TRACE 0x00000001
32 #define D_INFO 0x00000002
33 #define D_WARNING 0x00000004
34 #define D_ERROR 0x00000008
35 #define D_EMERG 0x00000010
36 #define D_CONSOLE 0x00000020
37 #define D_IOCTL 0x00000040
38 #define D_DPRINTF 0x00000080
39 #define D_OTHER 0x00000100
40
41 #define D_CANTMASK (D_ERROR | D_EMERG | D_WARNING | D_CONSOLE)
42 #define DEBUG_SUBSYSTEM S_UNDEFINED
43
44 int debug_init(void);
45 void debug_fini(void);
46 int spl_debug_mask2str(char *str, int size, unsigned long mask, int is_subsys);
47 int spl_debug_str2mask(unsigned long *mask, const char *str, int is_subsys);
48
49 extern unsigned long spl_debug_subsys;
50 extern unsigned long spl_debug_mask;
51 extern unsigned long spl_debug_printk;
52 extern int spl_debug_mb;
53 extern unsigned int spl_debug_binary;
54 extern unsigned int spl_debug_catastrophe;
55 extern unsigned int spl_debug_panic_on_bug;
56 extern char spl_debug_file_path[PATH_MAX];
57 extern unsigned int spl_console_ratelimit;
58 extern long spl_console_max_delay;
59 extern long spl_console_min_delay;
60 extern unsigned int spl_console_backoff;
61 extern unsigned int spl_debug_stack;
62
63 #define TCD_MAX_PAGES (5 << (20 - PAGE_SHIFT))
64 #define TCD_STOCK_PAGES (TCD_MAX_PAGES)
65 #define TRACE_CONSOLE_BUFFER_SIZE 1024
66
67 #define SPL_DEFAULT_MAX_DELAY (600 * HZ)
68 #define SPL_DEFAULT_MIN_DELAY ((HZ + 1) / 2)
69 #define SPL_DEFAULT_BACKOFF 2
70
71 #define DL_NOTHREAD 0x0001 /* Do not create a new thread */
72 #define DL_SINGLE_CPU 0x0002 /* Collect pages from this CPU */
73
74 typedef struct dumplog_priv {
75 wait_queue_head_t dp_waitq;
76 pid_t dp_pid;
77 int dp_flags;
78 atomic_t dp_done;
79 } dumplog_priv_t;
80
81 typedef struct {
82 unsigned long cdls_next;
83 int cdls_count;
84 long cdls_delay;
85 } spl_debug_limit_state_t;
86
87 /* Three trace data types */
88 typedef enum {
89 TCD_TYPE_PROC,
90 TCD_TYPE_SOFTIRQ,
91 TCD_TYPE_IRQ,
92 TCD_TYPE_MAX
93 } tcd_type_t;
94
95 union trace_data_union {
96 struct trace_cpu_data {
97 /* pages with trace records not yet processed by tracefiled */
98 struct list_head tcd_pages;
99 /* number of pages on ->tcd_pages */
100 unsigned long tcd_cur_pages;
101 /* Max number of pages allowed on ->tcd_pages */
102 unsigned long tcd_max_pages;
103
104 /*
105 * preallocated pages to write trace records into. Pages from
106 * ->tcd_stock_pages are moved to ->tcd_pages by spl_debug_msg().
107 *
108 * This list is necessary, because on some platforms it's
109 * impossible to perform efficient atomic page allocation in a
110 * non-blockable context.
111 *
112 * Such platforms fill ->tcd_stock_pages "on occasion", when
113 * tracing code is entered in blockable context.
114 *
115 * trace_get_tage_try() tries to get a page from
116 * ->tcd_stock_pages first and resorts to atomic page
117 * allocation only if this queue is empty. ->tcd_stock_pages
118 * is replenished when tracing code is entered in blocking
119 * context (darwin-tracefile.c:trace_get_tcd()). We try to
120 * maintain TCD_STOCK_PAGES (40 by default) pages in this
121 * queue. Atomic allocation is only required if more than
122 * TCD_STOCK_PAGES pagesful are consumed by trace records all
123 * emitted in non-blocking contexts. Which is quite unlikely.
124 */
125 struct list_head tcd_stock_pages;
126 /* number of pages on ->tcd_stock_pages */
127 unsigned long tcd_cur_stock_pages;
128
129 unsigned short tcd_shutting_down;
130 unsigned short tcd_cpu;
131 unsigned short tcd_type;
132 /* The factors to share debug memory. */
133 unsigned short tcd_pages_factor;
134 } tcd;
135 char __pad[L1_CACHE_ALIGN(sizeof(struct trace_cpu_data))];
136 };
137
138 extern union trace_data_union (*trace_data[TCD_TYPE_MAX])[NR_CPUS];
139
140 #define tcd_for_each(tcd, i, j) \
141 for (i = 0; trace_data[i] != NULL; i++) \
142 for (j = 0, ((tcd) = &(*trace_data[i])[j].tcd); \
143 j < num_possible_cpus(); j++, (tcd) = &(*trace_data[i])[j].tcd)
144
145 #define tcd_for_each_type_lock(tcd, i) \
146 for (i = 0; trace_data[i] && \
147 (tcd = &(*trace_data[i])[smp_processor_id()].tcd) && \
148 trace_lock_tcd(tcd); trace_unlock_tcd(tcd), i++)
149
150 struct trace_page {
151 struct page * page; /* page itself */
152 struct list_head linkage; /* Used by lists in trace_data_union */
153 unsigned int used; /* number of bytes used within this page */
154 unsigned short cpu; /* cpu that owns this page */
155 unsigned short type; /* type(context) of this page */
156 };
157
158 struct page_collection {
159 struct list_head pc_pages;
160 spinlock_t pc_lock;
161 int pc_want_daemon_pages;
162 };
163
164 #define SBUG() spl_debug_bug(__FILE__, __FUNCTION__, __LINE__, 0);
165
166 #ifdef NDEBUG
167
168 #define CDEBUG_STACK() (0)
169 #define CDEBUG(mask, format, a...) ((void)0)
170 #define CWARN(fmt, a...) ((void)0)
171 #define CERROR(fmt, a...) ((void)0)
172 #define CEMERG(fmt, a...) ((void)0)
173 #define CONSOLE(mask, fmt, a...) ((void)0)
174
175 #define ENTRY ((void)0)
176 #define EXIT ((void)0)
177 #define RETURN(x) return (x)
178 #define GOTO(x, y) { ((void)(y)); goto x; }
179
180 #define __ASSERT(x) ((void)0)
181 #define __ASSERT_TAGE_INVARIANT(x) ((void)0)
182 #define ASSERT(x) ((void)0)
183 #define VERIFY(x) ((void)(x))
184
185 #define VERIFY3_IMPL(x, y, z, t, f, c) if (x == z) ((void)0)
186
187 #define VERIFY3S(x,y,z) VERIFY3_IMPL(x, y, z, int64_t, "%ld", (long))
188 #define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%lu", (unsigned long))
189 #define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
190
191 #define ASSERT3S(x,y,z) VERIFY3S(x, y, z)
192 #define ASSERT3U(x,y,z) VERIFY3U(x, y, z)
193 #define ASSERT3P(x,y,z) VERIFY3P(x, y, z)
194
195 #else /* NDEBUG */
196
197 #ifdef __ia64__
198 #define CDEBUG_STACK() (THREAD_SIZE - \
199 ((unsigned long)__builtin_dwarf_cfa() & \
200 (THREAD_SIZE - 1)))
201 #else
202 #define CDEBUG_STACK() (THREAD_SIZE - \
203 ((unsigned long)__builtin_frame_address(0) & \
204 (THREAD_SIZE - 1)))
205 # endif /* __ia64__ */
206
207 /* DL_SINGLE_CPU flag is passed to spl_debug_bug() because we are about
208 * to over run our stack and likely damage at least one other unknown
209 * thread stack. We must finish generating the needed debug info within
210 * this thread context because once we yeild the CPU its very likely
211 * the system will crash.
212 */
213 #define __CHECK_STACK(file, func, line) \
214 do { \
215 if (unlikely(CDEBUG_STACK() > spl_debug_stack)) { \
216 spl_debug_stack = CDEBUG_STACK(); \
217 \
218 if (unlikely(CDEBUG_STACK() > (4 * THREAD_SIZE) / 5)) { \
219 spl_debug_msg(NULL, D_TRACE, D_WARNING, \
220 file, func, line, "Error " \
221 "exceeded maximum safe stack " \
222 "size (%lu/%lu)\n", \
223 CDEBUG_STACK(), THREAD_SIZE); \
224 spl_debug_bug(file, func, line, DL_SINGLE_CPU); \
225 } \
226 } \
227 } while (0)
228
229 #define CHECK_STACK() __CHECK_STACK(__FILE__, __func__, __LINE__)
230
231 /* ASSERTION that is safe to use within the debug system */
232 #define __ASSERT(cond) \
233 do { \
234 if (unlikely(!(cond))) { \
235 printk(KERN_ERR "ASSERTION(" #cond ") failed"); \
236 BUG(); \
237 } \
238 } while (0)
239
240 #define __ASSERT_TAGE_INVARIANT(tage) \
241 do { \
242 __ASSERT(tage != NULL); \
243 __ASSERT(tage->page != NULL); \
244 __ASSERT(tage->used <= PAGE_SIZE); \
245 __ASSERT(page_count(tage->page) > 0); \
246 } while(0)
247
248 /* ASSERTION that will debug log used outside the debug sysytem */
249 #define ASSERT(cond) \
250 do { \
251 CHECK_STACK(); \
252 \
253 if (unlikely(!(cond))) { \
254 spl_debug_msg(NULL, DEBUG_SUBSYSTEM, D_EMERG, \
255 __FILE__, __FUNCTION__, __LINE__, \
256 "ASSERTION(" #cond ") failed\n"); \
257 SBUG(); \
258 } \
259 } while (0)
260
261 #define ASSERTF(cond, fmt, a...) \
262 do { \
263 CHECK_STACK(); \
264 \
265 if (unlikely(!(cond))) { \
266 spl_debug_msg(NULL, DEBUG_SUBSYSTEM, D_EMERG, \
267 __FILE__, __FUNCTION__, __LINE__, \
268 "ASSERTION(" #cond ") failed:" fmt, \
269 ## a); \
270 SBUG(); \
271 } \
272 } while (0)
273
274 #define VERIFY3_IMPL(LEFT, OP, RIGHT, TYPE, FMT, CAST) \
275 do { \
276 CHECK_STACK(); \
277 \
278 if (!((TYPE)(LEFT) OP (TYPE)(RIGHT))) { \
279 spl_debug_msg(NULL, DEBUG_SUBSYSTEM, D_EMERG, \
280 __FILE__, __FUNCTION__, __LINE__, \
281 "VERIFY3(" FMT " " #OP " " FMT ")\n", \
282 CAST (LEFT), CAST (RIGHT)); \
283 SBUG(); \
284 } \
285 } while (0)
286
287 #define VERIFY3S(x,y,z) VERIFY3_IMPL(x, y, z, int64_t, "%ld", (long))
288 #define VERIFY3U(x,y,z) VERIFY3_IMPL(x, y, z, uint64_t, "%lu", (unsigned long))
289 #define VERIFY3P(x,y,z) VERIFY3_IMPL(x, y, z, uintptr_t, "%p", (void *))
290
291 #define ASSERT3S(x,y,z) VERIFY3S(x, y, z)
292 #define ASSERT3U(x,y,z) VERIFY3U(x, y, z)
293 #define ASSERT3P(x,y,z) VERIFY3P(x, y, z)
294
295 #define VERIFY(x) ASSERT(x)
296
297 #define __CDEBUG(cdls, subsys, mask, format, a...) \
298 do { \
299 CHECK_STACK(); \
300 \
301 if (((mask) & D_CANTMASK) != 0 || \
302 ((spl_debug_mask & (mask)) != 0 && \
303 (spl_debug_subsys & (subsys)) != 0)) \
304 spl_debug_msg(cdls, subsys, mask, \
305 __FILE__, __FUNCTION__, __LINE__, \
306 format, ## a); \
307 } while (0)
308
309 #define CDEBUG(mask, format, a...) \
310 __CDEBUG(NULL, DEBUG_SUBSYSTEM, mask, format, ## a)
311
312 #define __CDEBUG_LIMIT(subsys, mask, format, a...) \
313 do { \
314 static spl_debug_limit_state_t cdls; \
315 \
316 __CDEBUG(&cdls, subsys, mask, format, ## a); \
317 } while (0)
318
319 #define CDEBUG_LIMIT(mask, format, a...) \
320 __CDEBUG_LIMIT(DEBUG_SUBSYSTEM, mask, format, ## a)
321
322 #define CWARN(fmt, a...) CDEBUG_LIMIT(D_WARNING, fmt, ## a)
323 #define CERROR(fmt, a...) CDEBUG_LIMIT(D_ERROR, fmt, ## a)
324 #define CEMERG(fmt, a...) CDEBUG_LIMIT(D_EMERG, fmt, ## a)
325 #define CONSOLE(mask, fmt, a...) CDEBUG(D_CONSOLE | (mask), fmt, ## a)
326
327 #define GOTO(label, rc) \
328 do { \
329 long GOTO__ret = (long)(rc); \
330 CDEBUG(D_TRACE,"Process leaving via %s (rc=%lu : %ld : %lx)\n", \
331 #label, (unsigned long)GOTO__ret, (signed long)GOTO__ret,\
332 (signed long)GOTO__ret); \
333 goto label; \
334 } while (0)
335
336 #define RETURN(rc) \
337 do { \
338 typeof(rc) RETURN__ret = (rc); \
339 CDEBUG(D_TRACE, "Process leaving (rc=%lu : %ld : %lx)\n", \
340 (long)RETURN__ret, (long)RETURN__ret, (long)RETURN__ret);\
341 return RETURN__ret; \
342 } while (0)
343
344 #define __ENTRY(subsys) \
345 do { \
346 __CDEBUG(NULL, subsys, D_TRACE, "Process entered\n"); \
347 } while (0)
348
349 #define __EXIT(subsys) \
350 do { \
351 __CDEBUG(NULL, subsys, D_TRACE, "Process leaving\n"); \
352 } while(0)
353
354 #define ENTRY __ENTRY(DEBUG_SUBSYSTEM)
355 #define EXIT __EXIT(DEBUG_SUBSYSTEM)
356 #endif /* NDEBUG */
357
358 #define spl_debug_msg(cdls, subsys, mask, file, fn, line, format, a...) \
359 spl_debug_vmsg(cdls, subsys, mask, file, fn, \
360 line, NULL, NULL, format, ##a)
361
362 extern int spl_debug_vmsg(spl_debug_limit_state_t *cdls, int subsys, int mask,
363 const char *file, const char *fn, const int line,
364 const char *format1, va_list args, const char *format2, ...);
365
366 extern unsigned long spl_debug_set_mask(unsigned long mask);
367 extern unsigned long spl_debug_get_mask(void);
368 extern unsigned long spl_debug_set_subsys(unsigned long mask);
369 extern unsigned long spl_debug_get_subsys(void);
370 extern int spl_debug_set_mb(int mb);
371 extern int spl_debug_get_mb(void);
372
373 extern int spl_debug_dumplog(int flags);
374 extern void spl_debug_dumpstack(struct task_struct *tsk);
375 extern void spl_debug_bug(char *file, const char *func, const int line, int flags);
376
377 extern int spl_debug_clear_buffer(void);
378 extern int spl_debug_mark_buffer(char *text);
379
380 #ifdef __cplusplus
381 }
382 #endif
383
384 #endif /* SPL_DEBUG_H */