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