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