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