]> git.proxmox.com Git - mirror_spl-debian.git/blame - module/spl/spl-debug.c
Imported Upstream version 0.6.1
[mirror_spl-debian.git] / module / spl / spl-debug.c
CommitLineData
716154c5
BB
1/*****************************************************************************\
2 * Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
3 * Copyright (C) 2007 The Regents of the University of California.
4 * Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
5 * Written by Brian Behlendorf <behlendorf1@llnl.gov>.
715f6251 6 * UCRL-CODE-235197
57d1b188 7 *
716154c5 8 * This file is part of the SPL, Solaris Porting Layer.
d956cfac 9 * For details, see <http://zfsonlinux.org/>.
716154c5
BB
10 *
11 * The SPL is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
57d1b188 15 *
716154c5 16 * The SPL is distributed in the hope that it will be useful, but WITHOUT
715f6251 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 * for more details.
57d1b188 20 *
715f6251 21 * You should have received a copy of the GNU General Public License along
716154c5
BB
22 * with the SPL. If not, see <http://www.gnu.org/licenses/>.
23 *****************************************************************************
24 * Solaris Porting Layer (SPL) Debug Implementation.
25\*****************************************************************************/
57d1b188 26
27#include <linux/kmod.h>
28#include <linux/mm.h>
29#include <linux/vmalloc.h>
30#include <linux/pagemap.h>
31#include <linux/slab.h>
32#include <linux/ctype.h>
33#include <linux/kthread.h>
34#include <linux/hardirq.h>
35#include <linux/interrupt.h>
f6c81c5e 36#include <linux/spinlock.h>
ae4c36ad 37#include <linux/proc_compat.h>
f0ff89fc 38#include <linux/file_compat.h>
57d1b188 39#include <sys/sysmacros.h>
55abb092
BB
40#include <spl-debug.h>
41#include <spl-trace.h>
57d1b188 42#include <spl-ctl.h>
57d1b188 43
b17edc10
BB
44#ifdef SS_DEBUG_SUBSYS
45#undef SS_DEBUG_SUBSYS
57d1b188 46#endif
47
b17edc10 48#define SS_DEBUG_SUBSYS SS_DEBUG
57d1b188 49
4b2220f0
BB
50/* Debug log support enabled */
51#ifdef DEBUG_LOG
52
57d1b188 53unsigned long spl_debug_subsys = ~0;
54EXPORT_SYMBOL(spl_debug_subsys);
55abb092 55module_param(spl_debug_subsys, ulong, 0644);
57d1b188 56MODULE_PARM_DESC(spl_debug_subsys, "Subsystem debugging level mask.");
57
b17edc10 58unsigned long spl_debug_mask = SD_CANTMASK;
57d1b188 59EXPORT_SYMBOL(spl_debug_mask);
55abb092 60module_param(spl_debug_mask, ulong, 0644);
57d1b188 61MODULE_PARM_DESC(spl_debug_mask, "Debugging level mask.");
62
b17edc10 63unsigned long spl_debug_printk = SD_CANTMASK;
57d1b188 64EXPORT_SYMBOL(spl_debug_printk);
55abb092 65module_param(spl_debug_printk, ulong, 0644);
57d1b188 66MODULE_PARM_DESC(spl_debug_printk, "Console printk level mask.");
67
68int spl_debug_mb = -1;
69EXPORT_SYMBOL(spl_debug_mb);
70module_param(spl_debug_mb, int, 0644);
71MODULE_PARM_DESC(spl_debug_mb, "Total debug buffer size.");
72
73unsigned int spl_debug_binary = 1;
74EXPORT_SYMBOL(spl_debug_binary);
75
76unsigned int spl_debug_catastrophe;
77EXPORT_SYMBOL(spl_debug_catastrophe);
78
3626ae6a 79unsigned int spl_debug_panic_on_bug = 0;
57d1b188 80EXPORT_SYMBOL(spl_debug_panic_on_bug);
55abb092 81module_param(spl_debug_panic_on_bug, uint, 0644);
57d1b188 82MODULE_PARM_DESC(spl_debug_panic_on_bug, "Panic on BUG");
83
84static char spl_debug_file_name[PATH_MAX];
627a7497 85char spl_debug_file_path[PATH_MAX] = "/tmp/spl-log";
57d1b188 86
87unsigned int spl_console_ratelimit = 1;
88EXPORT_SYMBOL(spl_console_ratelimit);
89
90long spl_console_max_delay;
91EXPORT_SYMBOL(spl_console_max_delay);
92
93long spl_console_min_delay;
94EXPORT_SYMBOL(spl_console_min_delay);
95
96unsigned int spl_console_backoff = SPL_DEFAULT_BACKOFF;
97EXPORT_SYMBOL(spl_console_backoff);
98
99unsigned int spl_debug_stack;
100EXPORT_SYMBOL(spl_debug_stack);
101
102static int spl_panic_in_progress;
103
104union trace_data_union (*trace_data[TCD_TYPE_MAX])[NR_CPUS] __cacheline_aligned;
105char *trace_console_buffers[NR_CPUS][3];
106struct rw_semaphore trace_sem;
107atomic_t trace_tage_allocated = ATOMIC_INIT(0);
108
7fea96c0 109static int spl_debug_dump_all_pages(dumplog_priv_t *dp, char *);
57d1b188 110static void trace_fini(void);
111
112
113/* Memory percentage breakdown by type */
114static unsigned int pages_factor[TCD_TYPE_MAX] = {
115 80, /* 80% pages for TCD_TYPE_PROC */
116 10, /* 10% pages for TCD_TYPE_SOFTIRQ */
117 10 /* 10% pages for TCD_TYPE_IRQ */
118};
119
57d1b188 120const char *
121spl_debug_subsys2str(int subsys)
122{
123 switch (subsys) {
124 default:
125 return NULL;
b17edc10 126 case SS_UNDEFINED:
57d1b188 127 return "undefined";
b17edc10 128 case SS_ATOMIC:
57d1b188 129 return "atomic";
b17edc10 130 case SS_KOBJ:
57d1b188 131 return "kobj";
b17edc10 132 case SS_VNODE:
57d1b188 133 return "vnode";
b17edc10 134 case SS_TIME:
57d1b188 135 return "time";
b17edc10 136 case SS_RWLOCK:
57d1b188 137 return "rwlock";
b17edc10 138 case SS_THREAD:
57d1b188 139 return "thread";
b17edc10 140 case SS_CONDVAR:
57d1b188 141 return "condvar";
b17edc10 142 case SS_MUTEX:
57d1b188 143 return "mutex";
b17edc10 144 case SS_RNG:
57d1b188 145 return "rng";
b17edc10 146 case SS_TASKQ:
57d1b188 147 return "taskq";
b17edc10 148 case SS_KMEM:
57d1b188 149 return "kmem";
b17edc10 150 case SS_DEBUG:
e5bbd245 151 return "debug";
b17edc10 152 case SS_GENERIC:
e5bbd245 153 return "generic";
b17edc10 154 case SS_PROC:
e5bbd245 155 return "proc";
b17edc10 156 case SS_MODULE:
e5bbd245 157 return "module";
b17edc10 158 case SS_CRED:
ec7d53e9 159 return "cred";
b17edc10
BB
160 case SS_KSTAT:
161 return "kstat";
162 case SS_XDR:
163 return "xdr";
9fe45dc1
BB
164 case SS_TSD:
165 return "tsd";
5c1967eb
BB
166 case SS_ZLIB:
167 return "zlib";
b17edc10
BB
168 case SS_USER1:
169 return "user1";
170 case SS_USER2:
171 return "user2";
172 case SS_USER3:
173 return "user3";
174 case SS_USER4:
175 return "user4";
176 case SS_USER5:
177 return "user5";
178 case SS_USER6:
179 return "user6";
180 case SS_USER7:
181 return "user7";
182 case SS_USER8:
183 return "user8";
57d1b188 184 }
185}
186
187const char *
188spl_debug_dbg2str(int debug)
189{
190 switch (debug) {
191 default:
192 return NULL;
b17edc10 193 case SD_TRACE:
57d1b188 194 return "trace";
b17edc10 195 case SD_INFO:
57d1b188 196 return "info";
b17edc10 197 case SD_WARNING:
57d1b188 198 return "warning";
b17edc10 199 case SD_ERROR:
57d1b188 200 return "error";
b17edc10 201 case SD_EMERG:
57d1b188 202 return "emerg";
b17edc10 203 case SD_CONSOLE:
57d1b188 204 return "console";
b17edc10 205 case SD_IOCTL:
57d1b188 206 return "ioctl";
b17edc10 207 case SD_DPRINTF:
57d1b188 208 return "dprintf";
b17edc10 209 case SD_OTHER:
57d1b188 210 return "other";
211 }
212}
213
214int
215spl_debug_mask2str(char *str, int size, unsigned long mask, int is_subsys)
216{
217 const char *(*fn)(int bit) = is_subsys ? spl_debug_subsys2str :
218 spl_debug_dbg2str;
219 const char *token;
220 int i, bit, len = 0;
221
222 if (mask == 0) { /* "0" */
223 if (size > 0)
224 str[0] = '0';
225 len = 1;
226 } else { /* space-separated tokens */
227 for (i = 0; i < 32; i++) {
228 bit = 1 << i;
229
230 if ((mask & bit) == 0)
231 continue;
232
233 token = fn(bit);
234 if (token == NULL) /* unused bit */
235 continue;
236
237 if (len > 0) { /* separator? */
238 if (len < size)
239 str[len] = ' ';
240 len++;
241 }
242
243 while (*token != 0) {
244 if (len < size)
245 str[len] = *token;
246 token++;
247 len++;
248 }
249 }
250 }
251
252 /* terminate 'str' */
253 if (len < size)
254 str[len] = 0;
255 else
256 str[size - 1] = 0;
257
258 return len;
259}
260
261static int
262spl_debug_token2mask(int *mask, const char *str, int len, int is_subsys)
263{
264 const char *(*fn)(int bit) = is_subsys ? spl_debug_subsys2str :
265 spl_debug_dbg2str;
266 const char *token;
267 int i, j, bit;
268
269 /* match against known tokens */
270 for (i = 0; i < 32; i++) {
271 bit = 1 << i;
272
273 token = fn(bit);
274 if (token == NULL) /* unused? */
275 continue;
276
277 /* strcasecmp */
278 for (j = 0; ; j++) {
279 if (j == len) { /* end of token */
280 if (token[j] == 0) {
281 *mask = bit;
282 return 0;
283 }
284 break;
285 }
286
287 if (token[j] == 0)
288 break;
289
290 if (str[j] == token[j])
291 continue;
292
293 if (str[j] < 'A' || 'Z' < str[j])
294 break;
295
296 if (str[j] - 'A' + 'a' != token[j])
297 break;
298 }
299 }
300
301 return -EINVAL; /* no match */
302}
303
304int
305spl_debug_str2mask(unsigned long *mask, const char *str, int is_subsys)
306{
307 char op = 0;
308 int m = 0, matched, n, t;
309
310 /* Allow a number for backwards compatibility */
311 for (n = strlen(str); n > 0; n--)
312 if (!isspace(str[n-1]))
313 break;
314 matched = n;
315
316 if ((t = sscanf(str, "%i%n", &m, &matched)) >= 1 && matched == n) {
317 *mask = m;
318 return 0;
319 }
320
321 /* <str> must be a list of debug tokens or numbers separated by
322 * whitespace and optionally an operator ('+' or '-'). If an operator
323 * appears first in <str>, '*mask' is used as the starting point
324 * (relative), otherwise 0 is used (absolute). An operator applies to
325 * all following tokens up to the next operator. */
326 matched = 0;
327 while (*str != 0) {
328 while (isspace(*str)) /* skip whitespace */
329 str++;
330
331 if (*str == 0)
332 break;
333
334 if (*str == '+' || *str == '-') {
335 op = *str++;
336
337 /* op on first token == relative */
338 if (!matched)
339 m = *mask;
340
341 while (isspace(*str)) /* skip whitespace */
342 str++;
343
344 if (*str == 0) /* trailing op */
345 return -EINVAL;
346 }
347
348 /* find token length */
349 for (n = 0; str[n] != 0 && !isspace(str[n]); n++);
350
351 /* match token */
352 if (spl_debug_token2mask(&t, str, n, is_subsys) != 0)
353 return -EINVAL;
354
355 matched = 1;
356 if (op == '-')
357 m &= ~t;
358 else
359 m |= t;
360
361 str += n;
362 }
363
364 if (!matched)
365 return -EINVAL;
366
367 *mask = m;
368 return 0;
369}
370
57d1b188 371static void
372spl_debug_dumplog_internal(dumplog_priv_t *dp)
373{
374 void *journal_info;
375
376 journal_info = current->journal_info;
377 current->journal_info = NULL;
378
379 snprintf(spl_debug_file_name, sizeof(spl_debug_file_path) - 1,
380 "%s.%ld.%ld", spl_debug_file_path,
381 get_seconds(), (long)dp->dp_pid);
627a7497 382 printk("SPL: Dumping log to %s\n", spl_debug_file_name);
7fea96c0 383 spl_debug_dump_all_pages(dp, spl_debug_file_name);
57d1b188 384
385 current->journal_info = journal_info;
386}
387
388static int
389spl_debug_dumplog_thread(void *arg)
390{
391 dumplog_priv_t *dp = (dumplog_priv_t *)arg;
392
393 spl_debug_dumplog_internal(dp);
7fea96c0 394 atomic_set(&dp->dp_done, 1);
57d1b188 395 wake_up(&dp->dp_waitq);
3d061e9d 396 complete_and_exit(NULL, 0);
57d1b188 397
398 return 0; /* Unreachable */
399}
400
7fea96c0 401/* When flag is set do not use a new thread for the debug dump */
57d1b188 402int
7fea96c0 403spl_debug_dumplog(int flags)
57d1b188 404{
405 struct task_struct *tsk;
406 dumplog_priv_t dp;
57d1b188 407
7fea96c0 408 init_waitqueue_head(&dp.dp_waitq);
409 dp.dp_pid = current->pid;
410 dp.dp_flags = flags;
411 atomic_set(&dp.dp_done, 0);
57d1b188 412
7fea96c0 413 if (dp.dp_flags & DL_NOTHREAD) {
414 spl_debug_dumplog_internal(&dp);
415 } else {
57d1b188 416
7fea96c0 417 tsk = kthread_create(spl_debug_dumplog_thread,(void *)&dp,"spl_debug");
418 if (tsk == NULL)
419 return -ENOMEM;
420
421 wake_up_process(tsk);
422 wait_event(dp.dp_waitq, atomic_read(&dp.dp_done));
423 }
57d1b188 424
a8ac0b89 425 return 0;
57d1b188 426}
427EXPORT_SYMBOL(spl_debug_dumplog);
428
429static char *
430trace_get_console_buffer(void)
431{
432 int cpu = get_cpu();
433 int idx;
434
435 if (in_irq()) {
436 idx = 0;
437 } else if (in_softirq()) {
438 idx = 1;
439 } else {
440 idx = 2;
441 }
442
443 return trace_console_buffers[cpu][idx];
444}
445
446static void
447trace_put_console_buffer(char *buffer)
448{
449 put_cpu();
450}
451
f6c81c5e 452static int
453trace_lock_tcd(struct trace_cpu_data *tcd)
57d1b188 454{
f6c81c5e 455 __ASSERT(tcd->tcd_type < TCD_TYPE_MAX);
57d1b188 456
f6c81c5e 457 spin_lock_irqsave(&tcd->tcd_lock, tcd->tcd_lock_flags);
57d1b188 458
f6c81c5e 459 return 1;
57d1b188 460}
461
462static void
f6c81c5e 463trace_unlock_tcd(struct trace_cpu_data *tcd)
57d1b188 464{
f6c81c5e 465 __ASSERT(tcd->tcd_type < TCD_TYPE_MAX);
466
467 spin_unlock_irqrestore(&tcd->tcd_lock, tcd->tcd_lock_flags);
57d1b188 468}
469
f6c81c5e 470static struct trace_cpu_data *
471trace_get_tcd(void)
57d1b188 472{
f6c81c5e 473 int cpu;
474 struct trace_cpu_data *tcd;
475
476 cpu = get_cpu();
477 if (in_irq())
478 tcd = &(*trace_data[TCD_TYPE_IRQ])[cpu].tcd;
479 else if (in_softirq())
480 tcd = &(*trace_data[TCD_TYPE_SOFTIRQ])[cpu].tcd;
481 else
482 tcd = &(*trace_data[TCD_TYPE_PROC])[cpu].tcd;
57d1b188 483
f6c81c5e 484 trace_lock_tcd(tcd);
57d1b188 485
f6c81c5e 486 return tcd;
57d1b188 487}
488
489static void
f6c81c5e 490trace_put_tcd (struct trace_cpu_data *tcd)
57d1b188 491{
f6c81c5e 492 trace_unlock_tcd(tcd);
57d1b188 493
f6c81c5e 494 put_cpu();
57d1b188 495}
496
497static void
498trace_set_debug_header(struct spl_debug_header *header, int subsys,
499 int mask, const int line, unsigned long stack)
500{
501 struct timeval tv;
502
503 do_gettimeofday(&tv);
504
505 header->ph_subsys = subsys;
506 header->ph_mask = mask;
507 header->ph_cpu_id = smp_processor_id();
508 header->ph_sec = (__u32)tv.tv_sec;
509 header->ph_usec = tv.tv_usec;
510 header->ph_stack = stack;
511 header->ph_pid = current->pid;
512 header->ph_line_num = line;
513
514 return;
515}
516
517static void
518trace_print_to_console(struct spl_debug_header *hdr, int mask, const char *buf,
519 int len, const char *file, const char *fn)
520{
521 char *prefix = "SPL", *ptype = NULL;
522
b17edc10 523 if ((mask & SD_EMERG) != 0) {
57d1b188 524 prefix = "SPLError";
525 ptype = KERN_EMERG;
b17edc10 526 } else if ((mask & SD_ERROR) != 0) {
57d1b188 527 prefix = "SPLError";
528 ptype = KERN_ERR;
b17edc10 529 } else if ((mask & SD_WARNING) != 0) {
57d1b188 530 prefix = "SPL";
531 ptype = KERN_WARNING;
b17edc10 532 } else if ((mask & (SD_CONSOLE | spl_debug_printk)) != 0) {
57d1b188 533 prefix = "SPL";
534 ptype = KERN_INFO;
535 }
536
b17edc10 537 if ((mask & SD_CONSOLE) != 0) {
57d1b188 538 printk("%s%s: %.*s", ptype, prefix, len, buf);
539 } else {
892d5106 540 printk("%s%s: %d:%d:(%s:%d:%s()) %.*s", ptype, prefix,
541 hdr->ph_pid, hdr->ph_stack, file,
542 hdr->ph_line_num, fn, len, buf);
57d1b188 543 }
544
545 return;
546}
547
548static int
549trace_max_debug_mb(void)
550{
551 return MAX(512, ((num_physpages >> (20 - PAGE_SHIFT)) * 80) / 100);
552}
553
57d1b188 554static struct trace_page *
555tage_alloc(int gfp)
556{
557 struct page *page;
558 struct trace_page *tage;
559
560 page = alloc_pages(gfp | __GFP_NOWARN, 0);
561 if (page == NULL)
562 return NULL;
563
564 tage = kmalloc(sizeof(*tage), gfp);
565 if (tage == NULL) {
566 __free_pages(page, 0);
567 return NULL;
568 }
569
570 tage->page = page;
571 atomic_inc(&trace_tage_allocated);
572
573 return tage;
574}
575
576static void
577tage_free(struct trace_page *tage)
578{
579 __ASSERT(tage != NULL);
580 __ASSERT(tage->page != NULL);
581
582 __free_pages(tage->page, 0);
583 kfree(tage);
584 atomic_dec(&trace_tage_allocated);
585}
586
587static struct trace_page *
588tage_from_list(struct list_head *list)
589{
590 return list_entry(list, struct trace_page, linkage);
591}
592
593static void
594tage_to_tail(struct trace_page *tage, struct list_head *queue)
595{
596 __ASSERT(tage != NULL);
597 __ASSERT(queue != NULL);
598
599 list_move_tail(&tage->linkage, queue);
600}
601
602/* try to return a page that has 'len' bytes left at the end */
603static struct trace_page *
604trace_get_tage_try(struct trace_cpu_data *tcd, unsigned long len)
605{
606 struct trace_page *tage;
607
608 if (tcd->tcd_cur_pages > 0) {
609 __ASSERT(!list_empty(&tcd->tcd_pages));
610 tage = tage_from_list(tcd->tcd_pages.prev);
611 if (tage->used + len <= PAGE_SIZE)
612 return tage;
613 }
614
615 if (tcd->tcd_cur_pages < tcd->tcd_max_pages) {
616 if (tcd->tcd_cur_stock_pages > 0) {
617 tage = tage_from_list(tcd->tcd_stock_pages.prev);
618 tcd->tcd_cur_stock_pages--;
619 list_del_init(&tage->linkage);
620 } else {
621 tage = tage_alloc(GFP_ATOMIC);
622 if (tage == NULL) {
623 printk(KERN_WARNING
624 "failure to allocate a tage (%ld)\n",
625 tcd->tcd_cur_pages);
626 return NULL;
627 }
628 }
629
630 tage->used = 0;
631 tage->cpu = smp_processor_id();
632 tage->type = tcd->tcd_type;
633 list_add_tail(&tage->linkage, &tcd->tcd_pages);
634 tcd->tcd_cur_pages++;
635
636 return tage;
637 }
638
639 return NULL;
640}
641
642/* return a page that has 'len' bytes left at the end */
643static struct trace_page *
644trace_get_tage(struct trace_cpu_data *tcd, unsigned long len)
645{
646 struct trace_page *tage;
647
648 __ASSERT(len <= PAGE_SIZE);
649
650 tage = trace_get_tage_try(tcd, len);
651 if (tage)
652 return tage;
653
654 if (tcd->tcd_cur_pages > 0) {
655 tage = tage_from_list(tcd->tcd_pages.next);
656 tage->used = 0;
657 tage_to_tail(tage, &tcd->tcd_pages);
658 }
659
660 return tage;
661}
662
663int
55abb092
BB
664spl_debug_msg(void *arg, int subsys, int mask, const char *file,
665 const char *fn, const int line, const char *format, ...)
57d1b188 666{
55abb092 667 spl_debug_limit_state_t *cdls = arg;
57d1b188 668 struct trace_cpu_data *tcd = NULL;
b02e9b24 669 struct spl_debug_header header = { 0, };
57d1b188 670 struct trace_page *tage;
671 /* string_buf is used only if tcd != NULL, and is always set then */
672 char *string_buf = NULL;
673 char *debug_buf;
674 int known_size;
675 int needed = 85; /* average message length */
676 int max_nob;
677 va_list ap;
678 int i;
57d1b188 679
55abb092 680 if (subsys == 0)
b17edc10 681 subsys = SS_DEBUG_SUBSYS;
55abb092
BB
682
683 if (mask == 0)
b17edc10 684 mask = SD_EMERG;
55abb092 685
57d1b188 686 if (strchr(file, '/'))
687 file = strrchr(file, '/') + 1;
688
57d1b188 689 tcd = trace_get_tcd();
9baf44bc 690 trace_set_debug_header(&header, subsys, mask, line, 0);
57d1b188 691 if (tcd == NULL)
692 goto console;
693
694 if (tcd->tcd_shutting_down) {
695 trace_put_tcd(tcd);
696 tcd = NULL;
697 goto console;
698 }
699
700 known_size = strlen(file) + 1;
701 if (fn)
702 known_size += strlen(fn) + 1;
703
704 if (spl_debug_binary)
705 known_size += sizeof(header);
706
707 /* '2' used because vsnprintf returns real size required for output
708 * _without_ terminating NULL. */
709 for (i = 0; i < 2; i++) {
710 tage = trace_get_tage(tcd, needed + known_size + 1);
711 if (tage == NULL) {
712 if (needed + known_size > PAGE_SIZE)
b17edc10 713 mask |= SD_ERROR;
57d1b188 714
715 trace_put_tcd(tcd);
716 tcd = NULL;
717 goto console;
718 }
719
720 string_buf = (char *)page_address(tage->page) +
721 tage->used + known_size;
722
723 max_nob = PAGE_SIZE - tage->used - known_size;
724 if (max_nob <= 0) {
725 printk(KERN_EMERG "negative max_nob: %i\n", max_nob);
b17edc10 726 mask |= SD_ERROR;
57d1b188 727 trace_put_tcd(tcd);
728 tcd = NULL;
729 goto console;
730 }
731
732 needed = 0;
55abb092 733 if (format) {
55abb092 734 va_start(ap, format);
8b0eb3f0 735 needed += vsnprintf(string_buf, max_nob, format, ap);
57d1b188 736 va_end(ap);
737 }
738
739 if (needed < max_nob)
740 break;
741 }
742
57d1b188 743 header.ph_len = known_size + needed;
744 debug_buf = (char *)page_address(tage->page) + tage->used;
745
746 if (spl_debug_binary) {
747 memcpy(debug_buf, &header, sizeof(header));
748 tage->used += sizeof(header);
749 debug_buf += sizeof(header);
750 }
751
752 strcpy(debug_buf, file);
753 tage->used += strlen(file) + 1;
754 debug_buf += strlen(file) + 1;
755
756 if (fn) {
757 strcpy(debug_buf, fn);
758 tage->used += strlen(fn) + 1;
759 debug_buf += strlen(fn) + 1;
760 }
761
762 __ASSERT(debug_buf == string_buf);
763
764 tage->used += needed;
765 __ASSERT (tage->used <= PAGE_SIZE);
766
767console:
768 if ((mask & spl_debug_printk) == 0) {
769 /* no console output requested */
770 if (tcd != NULL)
771 trace_put_tcd(tcd);
772 return 1;
773 }
774
775 if (cdls != NULL) {
776 if (spl_console_ratelimit && cdls->cdls_next != 0 &&
777 !time_before(cdls->cdls_next, jiffies)) {
778 /* skipping a console message */
779 cdls->cdls_count++;
780 if (tcd != NULL)
781 trace_put_tcd(tcd);
782 return 1;
783 }
784
785 if (time_before(cdls->cdls_next + spl_console_max_delay +
786 (10 * HZ), jiffies)) {
787 /* last timeout was a long time ago */
788 cdls->cdls_delay /= spl_console_backoff * 4;
789 } else {
790 cdls->cdls_delay *= spl_console_backoff;
791
792 if (cdls->cdls_delay < spl_console_min_delay)
793 cdls->cdls_delay = spl_console_min_delay;
794 else if (cdls->cdls_delay > spl_console_max_delay)
795 cdls->cdls_delay = spl_console_max_delay;
796 }
797
798 /* ensure cdls_next is never zero after it's been seen */
799 cdls->cdls_next = (jiffies + cdls->cdls_delay) | 1;
800 }
801
802 if (tcd != NULL) {
803 trace_print_to_console(&header, mask, string_buf, needed, file, fn);
804 trace_put_tcd(tcd);
805 } else {
806 string_buf = trace_get_console_buffer();
807
808 needed = 0;
55abb092 809 if (format != NULL) {
8b0eb3f0
BB
810 va_start(ap, format);
811 needed += vsnprintf(string_buf,
812 TRACE_CONSOLE_BUFFER_SIZE, format, ap);
813 va_end(ap);
57d1b188 814 }
815 trace_print_to_console(&header, mask,
816 string_buf, needed, file, fn);
817
818 trace_put_console_buffer(string_buf);
819 }
820
821 if (cdls != NULL && cdls->cdls_count != 0) {
822 string_buf = trace_get_console_buffer();
823
824 needed = snprintf(string_buf, TRACE_CONSOLE_BUFFER_SIZE,
825 "Skipped %d previous similar message%s\n",
826 cdls->cdls_count, (cdls->cdls_count > 1) ? "s" : "");
827
828 trace_print_to_console(&header, mask,
829 string_buf, needed, file, fn);
830
831 trace_put_console_buffer(string_buf);
832 cdls->cdls_count = 0;
833 }
834
835 return 0;
836}
55abb092 837EXPORT_SYMBOL(spl_debug_msg);
57d1b188 838
839/* Do the collect_pages job on a single CPU: assumes that all other
840 * CPUs have been stopped during a panic. If this isn't true for
841 * some arch, this will have to be implemented separately in each arch.
842 */
843static void
7fea96c0 844collect_pages_from_single_cpu(struct page_collection *pc)
57d1b188 845{
846 struct trace_cpu_data *tcd;
847 int i, j;
848
849 tcd_for_each(tcd, i, j) {
850 list_splice_init(&tcd->tcd_pages, &pc->pc_pages);
851 tcd->tcd_cur_pages = 0;
852 }
853}
854
855static void
f6c81c5e 856collect_pages_on_all_cpus(struct page_collection *pc)
57d1b188 857{
858 struct trace_cpu_data *tcd;
f6c81c5e 859 int i, cpu;
57d1b188 860
861 spin_lock(&pc->pc_lock);
f6c81c5e 862 for_each_possible_cpu(cpu) {
863 tcd_for_each_type_lock(tcd, i, cpu) {
864 list_splice_init(&tcd->tcd_pages, &pc->pc_pages);
865 tcd->tcd_cur_pages = 0;
866 }
57d1b188 867 }
868 spin_unlock(&pc->pc_lock);
869}
870
871static void
7fea96c0 872collect_pages(dumplog_priv_t *dp, struct page_collection *pc)
57d1b188 873{
874 INIT_LIST_HEAD(&pc->pc_pages);
875
7fea96c0 876 if (spl_panic_in_progress || dp->dp_flags & DL_SINGLE_CPU)
877 collect_pages_from_single_cpu(pc);
57d1b188 878 else
f6c81c5e 879 collect_pages_on_all_cpus(pc);
57d1b188 880}
881
882static void
f6c81c5e 883put_pages_back_on_all_cpus(struct page_collection *pc)
57d1b188 884{
57d1b188 885 struct trace_cpu_data *tcd;
886 struct list_head *cur_head;
887 struct trace_page *tage;
888 struct trace_page *tmp;
f6c81c5e 889 int i, cpu;
57d1b188 890
891 spin_lock(&pc->pc_lock);
57d1b188 892
f6c81c5e 893 for_each_possible_cpu(cpu) {
894 tcd_for_each_type_lock(tcd, i, cpu) {
895 cur_head = tcd->tcd_pages.next;
57d1b188 896
f6c81c5e 897 list_for_each_entry_safe(tage, tmp, &pc->pc_pages,
898 linkage) {
f6c81c5e 899 if (tage->cpu != cpu || tage->type != i)
900 continue;
57d1b188 901
f6c81c5e 902 tage_to_tail(tage, cur_head);
903 tcd->tcd_cur_pages++;
904 }
57d1b188 905 }
906 }
f6c81c5e 907
57d1b188 908 spin_unlock(&pc->pc_lock);
909}
910
911static void
912put_pages_back(struct page_collection *pc)
913{
914 if (!spl_panic_in_progress)
f6c81c5e 915 put_pages_back_on_all_cpus(pc);
57d1b188 916}
917
57d1b188 918static int
7fea96c0 919spl_debug_dump_all_pages(dumplog_priv_t *dp, char *filename)
57d1b188 920{
921 struct page_collection pc;
922 struct file *filp;
923 struct trace_page *tage;
924 struct trace_page *tmp;
925 mm_segment_t oldfs;
926 int rc = 0;
927
928 down_write(&trace_sem);
929
f0ff89fc 930 filp = spl_filp_open(filename, O_CREAT|O_EXCL|O_WRONLY|O_LARGEFILE,
57d1b188 931 0600, &rc);
932 if (filp == NULL) {
933 if (rc != -EEXIST)
934 printk(KERN_ERR "SPL: Can't open %s for dump: %d\n",
935 filename, rc);
936 goto out;
937 }
938
939 spin_lock_init(&pc.pc_lock);
7fea96c0 940 collect_pages(dp, &pc);
57d1b188 941 if (list_empty(&pc.pc_pages)) {
942 rc = 0;
943 goto close;
944 }
945
946 oldfs = get_fs();
947 set_fs(get_ds());
948
949 list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) {
f0ff89fc
BB
950 rc = spl_filp_write(filp, page_address(tage->page),
951 tage->used, spl_filp_poff(filp));
57d1b188 952 if (rc != (int)tage->used) {
953 printk(KERN_WARNING "SPL: Wanted to write %u "
954 "but wrote %d\n", tage->used, rc);
955 put_pages_back(&pc);
956 __ASSERT(list_empty(&pc.pc_pages));
957 break;
958 }
959 list_del(&tage->linkage);
960 tage_free(tage);
961 }
962
963 set_fs(oldfs);
964
f0ff89fc 965 rc = spl_filp_fsync(filp, 1);
57d1b188 966 if (rc)
967 printk(KERN_ERR "SPL: Unable to sync: %d\n", rc);
968 close:
f0ff89fc 969 spl_filp_close(filp);
57d1b188 970 out:
971 up_write(&trace_sem);
972
973 return rc;
974}
975
976static void
977spl_debug_flush_pages(void)
978{
7fea96c0 979 dumplog_priv_t dp;
57d1b188 980 struct page_collection pc;
981 struct trace_page *tage;
982 struct trace_page *tmp;
983
984 spin_lock_init(&pc.pc_lock);
7fea96c0 985 init_waitqueue_head(&dp.dp_waitq);
986 dp.dp_pid = current->pid;
987 dp.dp_flags = 0;
988 atomic_set(&dp.dp_done, 0);
57d1b188 989
7fea96c0 990 collect_pages(&dp, &pc);
57d1b188 991 list_for_each_entry_safe(tage, tmp, &pc.pc_pages, linkage) {
57d1b188 992 list_del(&tage->linkage);
993 tage_free(tage);
994 }
995}
996
997unsigned long
998spl_debug_set_mask(unsigned long mask) {
999 spl_debug_mask = mask;
1000 return 0;
1001}
1002EXPORT_SYMBOL(spl_debug_set_mask);
1003
1004unsigned long
1005spl_debug_get_mask(void) {
1006 return spl_debug_mask;
1007}
1008EXPORT_SYMBOL(spl_debug_get_mask);
1009
1010unsigned long
1011spl_debug_set_subsys(unsigned long subsys) {
1012 spl_debug_subsys = subsys;
1013 return 0;
1014}
1015EXPORT_SYMBOL(spl_debug_set_subsys);
1016
1017unsigned long
1018spl_debug_get_subsys(void) {
1019 return spl_debug_subsys;
1020}
1021EXPORT_SYMBOL(spl_debug_get_subsys);
1022
1023int
1024spl_debug_set_mb(int mb)
1025{
1026 int i, j, pages;
1027 int limit = trace_max_debug_mb();
1028 struct trace_cpu_data *tcd;
1029
1030 if (mb < num_possible_cpus()) {
1031 printk(KERN_ERR "SPL: Refusing to set debug buffer size to "
1032 "%dMB - lower limit is %d\n", mb, num_possible_cpus());
1033 return -EINVAL;
1034 }
1035
1036 if (mb > limit) {
1037 printk(KERN_ERR "SPL: Refusing to set debug buffer size to "
1038 "%dMB - upper limit is %d\n", mb, limit);
1039 return -EINVAL;
1040 }
1041
1042 mb /= num_possible_cpus();
1043 pages = mb << (20 - PAGE_SHIFT);
1044
1045 down_write(&trace_sem);
1046
1047 tcd_for_each(tcd, i, j)
1048 tcd->tcd_max_pages = (pages * tcd->tcd_pages_factor) / 100;
1049
1050 up_write(&trace_sem);
1051
1052 return 0;
1053}
1054EXPORT_SYMBOL(spl_debug_set_mb);
1055
1056int
1057spl_debug_get_mb(void)
1058{
1059 int i, j;
1060 struct trace_cpu_data *tcd;
1061 int total_pages = 0;
1062
1063 down_read(&trace_sem);
1064
1065 tcd_for_each(tcd, i, j)
1066 total_pages += tcd->tcd_max_pages;
1067
1068 up_read(&trace_sem);
1069
1070 return (total_pages >> (20 - PAGE_SHIFT)) + 1;
1071}
1072EXPORT_SYMBOL(spl_debug_get_mb);
1073
1074void spl_debug_dumpstack(struct task_struct *tsk)
1075{
1076 extern void show_task(struct task_struct *);
1077
1078 if (tsk == NULL)
1079 tsk = current;
1080
627a7497 1081 printk("SPL: Showing stack for process %d\n", tsk->pid);
57d86234 1082 dump_stack();
57d1b188 1083}
1084EXPORT_SYMBOL(spl_debug_dumpstack);
1085
7fea96c0 1086void spl_debug_bug(char *file, const char *func, const int line, int flags)
57d1b188 1087{
1088 spl_debug_catastrophe = 1;
b17edc10 1089 spl_debug_msg(NULL, 0, SD_EMERG, file, func, line, "SPL PANIC\n");
57d1b188 1090
55abb092
BB
1091 if (in_interrupt())
1092 panic("SPL PANIC in interrupt.\n");
57d1b188 1093
97f8f6d7
BB
1094 if (in_atomic() || irqs_disabled())
1095 flags |= DL_NOTHREAD;
1096
57d1b188 1097 /* Ensure all debug pages and dumped by current cpu */
1098 if (spl_debug_panic_on_bug)
1099 spl_panic_in_progress = 1;
1100
1101 spl_debug_dumpstack(NULL);
57d1b188 1102
d956cfac
AX
1103 if (spl_debug_panic_on_bug) {
1104 spl_debug_dumplog(flags);
55abb092 1105 panic("SPL PANIC");
d956cfac 1106 }
57d1b188 1107
1108 set_task_state(current, TASK_UNINTERRUPTIBLE);
1109 while (1)
1110 schedule();
1111}
1112EXPORT_SYMBOL(spl_debug_bug);
1113
1114int
1115spl_debug_clear_buffer(void)
1116{
1117 spl_debug_flush_pages();
1118 return 0;
1119}
1120EXPORT_SYMBOL(spl_debug_clear_buffer);
1121
1122int
1123spl_debug_mark_buffer(char *text)
1124{
b17edc10
BB
1125 SDEBUG(SD_WARNING, "*************************************\n");
1126 SDEBUG(SD_WARNING, "DEBUG MARKER: %s\n", text);
1127 SDEBUG(SD_WARNING, "*************************************\n");
57d1b188 1128
1129 return 0;
1130}
1131EXPORT_SYMBOL(spl_debug_mark_buffer);
1132
57d1b188 1133static int
1134trace_init(int max_pages)
1135{
1136 struct trace_cpu_data *tcd;
1137 int i, j;
1138
1139 init_rwsem(&trace_sem);
1140
1141 /* initialize trace_data */
1142 memset(trace_data, 0, sizeof(trace_data));
1143 for (i = 0; i < TCD_TYPE_MAX; i++) {
1144 trace_data[i] = kmalloc(sizeof(union trace_data_union) *
1145 NR_CPUS, GFP_KERNEL);
1146 if (trace_data[i] == NULL)
1147 goto out;
1148 }
1149
1150 tcd_for_each(tcd, i, j) {
f6c81c5e 1151 spin_lock_init(&tcd->tcd_lock);
57d1b188 1152 tcd->tcd_pages_factor = pages_factor[i];
1153 tcd->tcd_type = i;
1154 tcd->tcd_cpu = j;
1155 INIT_LIST_HEAD(&tcd->tcd_pages);
1156 INIT_LIST_HEAD(&tcd->tcd_stock_pages);
1157 tcd->tcd_cur_pages = 0;
1158 tcd->tcd_cur_stock_pages = 0;
1159 tcd->tcd_max_pages = (max_pages * pages_factor[i]) / 100;
1160 tcd->tcd_shutting_down = 0;
1161 }
1162
1163 for (i = 0; i < num_possible_cpus(); i++) {
1164 for (j = 0; j < 3; j++) {
1165 trace_console_buffers[i][j] =
1166 kmalloc(TRACE_CONSOLE_BUFFER_SIZE,
1167 GFP_KERNEL);
1168
1169 if (trace_console_buffers[i][j] == NULL)
1170 goto out;
1171 }
1172 }
1173
1174 return 0;
1175out:
1176 trace_fini();
1177 printk(KERN_ERR "SPL: Insufficient memory for debug logs\n");
1178 return -ENOMEM;
1179}
1180
1181int
1114ae6a 1182spl_debug_init(void)
57d1b188 1183{
1184 int rc, max = spl_debug_mb;
1185
1186 spl_console_max_delay = SPL_DEFAULT_MAX_DELAY;
1187 spl_console_min_delay = SPL_DEFAULT_MIN_DELAY;
1188
1189 /* If spl_debug_mb is set to an invalid value or uninitialized
1190 * then just make the total buffers smp_num_cpus TCD_MAX_PAGES */
1191 if (max > (num_physpages >> (20 - 2 - PAGE_SHIFT)) / 5 ||
1192 max >= 512 || max < 0) {
1193 max = TCD_MAX_PAGES;
1194 } else {
1195 max = (max / num_online_cpus()) << (20 - PAGE_SHIFT);
1196 }
1197
1198 rc = trace_init(max);
1199 if (rc)
1200 return rc;
1201
d50bd9e2 1202 return rc;
57d1b188 1203}
1204
1205static void
f6c81c5e 1206trace_cleanup_on_all_cpus(void)
57d1b188 1207{
1208 struct trace_cpu_data *tcd;
1209 struct trace_page *tage;
1210 struct trace_page *tmp;
f6c81c5e 1211 int i, cpu;
57d1b188 1212
f6c81c5e 1213 for_each_possible_cpu(cpu) {
1214 tcd_for_each_type_lock(tcd, i, cpu) {
1215 tcd->tcd_shutting_down = 1;
57d1b188 1216
f6c81c5e 1217 list_for_each_entry_safe(tage, tmp, &tcd->tcd_pages,
1218 linkage) {
f6c81c5e 1219 list_del(&tage->linkage);
1220 tage_free(tage);
1221 }
1222 tcd->tcd_cur_pages = 0;
57d1b188 1223 }
57d1b188 1224 }
1225}
1226
1227static void
1228trace_fini(void)
1229{
1230 int i, j;
1231
f6c81c5e 1232 trace_cleanup_on_all_cpus();
57d1b188 1233
1234 for (i = 0; i < num_possible_cpus(); i++) {
1235 for (j = 0; j < 3; j++) {
1236 if (trace_console_buffers[i][j] != NULL) {
1237 kfree(trace_console_buffers[i][j]);
1238 trace_console_buffers[i][j] = NULL;
1239 }
1240 }
1241 }
1242
124ca8a5 1243 for (i = 0; i < TCD_TYPE_MAX && trace_data[i] != NULL; i++) {
57d1b188 1244 kfree(trace_data[i]);
1245 trace_data[i] = NULL;
1246 }
1247}
1248
1249void
1114ae6a 1250spl_debug_fini(void)
57d1b188 1251{
57d1b188 1252 trace_fini();
57d1b188 1253}
4b2220f0
BB
1254
1255#endif /* DEBUG_LOG */