diff options
Diffstat (limited to 'lib/dynamic_debug.c')
| -rw-r--r-- | lib/dynamic_debug.c | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index b335acb43be2..75ca78f3a8c9 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | * Copyright (C) 2008 Jason Baron <jbaron@redhat.com> | 7 | * Copyright (C) 2008 Jason Baron <jbaron@redhat.com> |
| 8 | * By Greg Banks <gnb@melbourne.sgi.com> | 8 | * By Greg Banks <gnb@melbourne.sgi.com> |
| 9 | * Copyright (c) 2008 Silicon Graphics Inc. All Rights Reserved. | 9 | * Copyright (c) 2008 Silicon Graphics Inc. All Rights Reserved. |
| 10 | * Copyright (C) 2011 Bart Van Assche. All Rights Reserved. | ||
| 10 | */ | 11 | */ |
| 11 | 12 | ||
| 12 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| @@ -27,6 +28,8 @@ | |||
| 27 | #include <linux/debugfs.h> | 28 | #include <linux/debugfs.h> |
| 28 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 29 | #include <linux/jump_label.h> | 30 | #include <linux/jump_label.h> |
| 31 | #include <linux/hardirq.h> | ||
| 32 | #include <linux/sched.h> | ||
| 30 | 33 | ||
| 31 | extern struct _ddebug __start___verbose[]; | 34 | extern struct _ddebug __start___verbose[]; |
| 32 | extern struct _ddebug __stop___verbose[]; | 35 | extern struct _ddebug __stop___verbose[]; |
| @@ -63,15 +66,25 @@ static inline const char *basename(const char *path) | |||
| 63 | return tail ? tail+1 : path; | 66 | return tail ? tail+1 : path; |
| 64 | } | 67 | } |
| 65 | 68 | ||
| 69 | static struct { unsigned flag:8; char opt_char; } opt_array[] = { | ||
| 70 | { _DPRINTK_FLAGS_PRINT, 'p' }, | ||
| 71 | { _DPRINTK_FLAGS_INCL_MODNAME, 'm' }, | ||
| 72 | { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' }, | ||
| 73 | { _DPRINTK_FLAGS_INCL_LINENO, 'l' }, | ||
| 74 | { _DPRINTK_FLAGS_INCL_TID, 't' }, | ||
| 75 | }; | ||
| 76 | |||
| 66 | /* format a string into buf[] which describes the _ddebug's flags */ | 77 | /* format a string into buf[] which describes the _ddebug's flags */ |
| 67 | static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, | 78 | static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, |
| 68 | size_t maxlen) | 79 | size_t maxlen) |
| 69 | { | 80 | { |
| 70 | char *p = buf; | 81 | char *p = buf; |
| 82 | int i; | ||
| 71 | 83 | ||
| 72 | BUG_ON(maxlen < 4); | 84 | BUG_ON(maxlen < 4); |
| 73 | if (dp->flags & _DPRINTK_FLAGS_PRINT) | 85 | for (i = 0; i < ARRAY_SIZE(opt_array); ++i) |
| 74 | *p++ = 'p'; | 86 | if (dp->flags & opt_array[i].flag) |
| 87 | *p++ = opt_array[i].opt_char; | ||
| 75 | if (p == buf) | 88 | if (p == buf) |
| 76 | *p++ = '-'; | 89 | *p++ = '-'; |
| 77 | *p = '\0'; | 90 | *p = '\0'; |
| @@ -343,7 +356,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
| 343 | unsigned int *maskp) | 356 | unsigned int *maskp) |
| 344 | { | 357 | { |
| 345 | unsigned flags = 0; | 358 | unsigned flags = 0; |
| 346 | int op = '='; | 359 | int op = '=', i; |
| 347 | 360 | ||
| 348 | switch (*str) { | 361 | switch (*str) { |
| 349 | case '+': | 362 | case '+': |
| @@ -358,13 +371,14 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
| 358 | printk(KERN_INFO "%s: op='%c'\n", __func__, op); | 371 | printk(KERN_INFO "%s: op='%c'\n", __func__, op); |
| 359 | 372 | ||
| 360 | for ( ; *str ; ++str) { | 373 | for ( ; *str ; ++str) { |
| 361 | switch (*str) { | 374 | for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { |
| 362 | case 'p': | 375 | if (*str == opt_array[i].opt_char) { |
| 363 | flags |= _DPRINTK_FLAGS_PRINT; | 376 | flags |= opt_array[i].flag; |
| 364 | break; | 377 | break; |
| 365 | default: | 378 | } |
| 366 | return -EINVAL; | ||
| 367 | } | 379 | } |
| 380 | if (i < 0) | ||
| 381 | return -EINVAL; | ||
| 368 | } | 382 | } |
| 369 | if (flags == 0) | 383 | if (flags == 0) |
| 370 | return -EINVAL; | 384 | return -EINVAL; |
| @@ -413,6 +427,35 @@ static int ddebug_exec_query(char *query_string) | |||
| 413 | return 0; | 427 | return 0; |
| 414 | } | 428 | } |
| 415 | 429 | ||
| 430 | int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) | ||
| 431 | { | ||
| 432 | va_list args; | ||
| 433 | int res; | ||
| 434 | |||
| 435 | BUG_ON(!descriptor); | ||
| 436 | BUG_ON(!fmt); | ||
| 437 | |||
| 438 | va_start(args, fmt); | ||
| 439 | res = printk(KERN_DEBUG); | ||
| 440 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) { | ||
| 441 | if (in_interrupt()) | ||
| 442 | res += printk(KERN_CONT "<intr> "); | ||
| 443 | else | ||
| 444 | res += printk(KERN_CONT "[%d] ", task_pid_vnr(current)); | ||
| 445 | } | ||
| 446 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) | ||
| 447 | res += printk(KERN_CONT "%s:", descriptor->modname); | ||
| 448 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) | ||
| 449 | res += printk(KERN_CONT "%s:", descriptor->function); | ||
| 450 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO) | ||
| 451 | res += printk(KERN_CONT "%d ", descriptor->lineno); | ||
| 452 | res += vprintk(fmt, args); | ||
| 453 | va_end(args); | ||
| 454 | |||
| 455 | return res; | ||
| 456 | } | ||
| 457 | EXPORT_SYMBOL(__dynamic_pr_debug); | ||
| 458 | |||
| 416 | static __initdata char ddebug_setup_string[1024]; | 459 | static __initdata char ddebug_setup_string[1024]; |
| 417 | static __init int ddebug_setup_query(char *str) | 460 | static __init int ddebug_setup_query(char *str) |
| 418 | { | 461 | { |
