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 | { |