diff options
author | Bart Van Assche <bvanassche@acm.org> | 2011-01-23 11:17:24 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-02-03 18:39:16 -0500 |
commit | 8ba6ebf583f12da32036fc0f003ab4043e54692e (patch) | |
tree | 8fdd980d30fea50722b28fb5d782236174b2d188 /lib/dynamic_debug.c | |
parent | 9b99b7f84ea520d2ecaf816bde247a1ad07e454e (diff) |
Dynamic debug: Add more flags
Add flags that allow the user to specify via debugfs whether or not the
module name, function name, line number and/or thread ID have to be
included in the printed message.
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Cc: Greg Banks <gnb@fmeh.org>
Cc: Konrad Rzeszutek Wilk <konrad@darnok.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'lib/dynamic_debug.c')
-rw-r--r-- | lib/dynamic_debug.c | 60 |
1 files changed, 51 insertions, 9 deletions
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index b335acb43be2..863c83430964 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,7 @@ | |||
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> | ||
30 | 32 | ||
31 | extern struct _ddebug __start___verbose[]; | 33 | extern struct _ddebug __start___verbose[]; |
32 | extern struct _ddebug __stop___verbose[]; | 34 | extern struct _ddebug __stop___verbose[]; |
@@ -63,15 +65,25 @@ static inline const char *basename(const char *path) | |||
63 | return tail ? tail+1 : path; | 65 | return tail ? tail+1 : path; |
64 | } | 66 | } |
65 | 67 | ||
68 | static struct { unsigned flag:8; char opt_char; } opt_array[] = { | ||
69 | { _DPRINTK_FLAGS_PRINT, 'p' }, | ||
70 | { _DPRINTK_FLAGS_INCL_MODNAME, 'm' }, | ||
71 | { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' }, | ||
72 | { _DPRINTK_FLAGS_INCL_LINENO, 'l' }, | ||
73 | { _DPRINTK_FLAGS_INCL_TID, 't' }, | ||
74 | }; | ||
75 | |||
66 | /* format a string into buf[] which describes the _ddebug's flags */ | 76 | /* format a string into buf[] which describes the _ddebug's flags */ |
67 | static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, | 77 | static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, |
68 | size_t maxlen) | 78 | size_t maxlen) |
69 | { | 79 | { |
70 | char *p = buf; | 80 | char *p = buf; |
81 | int i; | ||
71 | 82 | ||
72 | BUG_ON(maxlen < 4); | 83 | BUG_ON(maxlen < 4); |
73 | if (dp->flags & _DPRINTK_FLAGS_PRINT) | 84 | for (i = 0; i < ARRAY_SIZE(opt_array); ++i) |
74 | *p++ = 'p'; | 85 | if (dp->flags & opt_array[i].flag) |
86 | *p++ = opt_array[i].opt_char; | ||
75 | if (p == buf) | 87 | if (p == buf) |
76 | *p++ = '-'; | 88 | *p++ = '-'; |
77 | *p = '\0'; | 89 | *p = '\0'; |
@@ -343,7 +355,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
343 | unsigned int *maskp) | 355 | unsigned int *maskp) |
344 | { | 356 | { |
345 | unsigned flags = 0; | 357 | unsigned flags = 0; |
346 | int op = '='; | 358 | int op = '=', i; |
347 | 359 | ||
348 | switch (*str) { | 360 | switch (*str) { |
349 | case '+': | 361 | case '+': |
@@ -358,13 +370,14 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
358 | printk(KERN_INFO "%s: op='%c'\n", __func__, op); | 370 | printk(KERN_INFO "%s: op='%c'\n", __func__, op); |
359 | 371 | ||
360 | for ( ; *str ; ++str) { | 372 | for ( ; *str ; ++str) { |
361 | switch (*str) { | 373 | for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { |
362 | case 'p': | 374 | if (*str == opt_array[i].opt_char) { |
363 | flags |= _DPRINTK_FLAGS_PRINT; | 375 | flags |= opt_array[i].flag; |
364 | break; | 376 | break; |
365 | default: | 377 | } |
366 | return -EINVAL; | ||
367 | } | 378 | } |
379 | if (i < 0) | ||
380 | return -EINVAL; | ||
368 | } | 381 | } |
369 | if (flags == 0) | 382 | if (flags == 0) |
370 | return -EINVAL; | 383 | return -EINVAL; |
@@ -413,6 +426,35 @@ static int ddebug_exec_query(char *query_string) | |||
413 | return 0; | 426 | return 0; |
414 | } | 427 | } |
415 | 428 | ||
429 | int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) | ||
430 | { | ||
431 | va_list args; | ||
432 | int res; | ||
433 | |||
434 | BUG_ON(!descriptor); | ||
435 | BUG_ON(!fmt); | ||
436 | |||
437 | va_start(args, fmt); | ||
438 | res = printk(KERN_DEBUG); | ||
439 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) { | ||
440 | if (in_interrupt()) | ||
441 | res += printk(KERN_CONT "<intr> "); | ||
442 | else | ||
443 | res += printk(KERN_CONT "[%d] ", task_pid_vnr(current)); | ||
444 | } | ||
445 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) | ||
446 | res += printk(KERN_CONT "%s:", descriptor->modname); | ||
447 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) | ||
448 | res += printk(KERN_CONT "%s:", descriptor->function); | ||
449 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO) | ||
450 | res += printk(KERN_CONT "%d ", descriptor->lineno); | ||
451 | res += vprintk(fmt, args); | ||
452 | va_end(args); | ||
453 | |||
454 | return res; | ||
455 | } | ||
456 | EXPORT_SYMBOL(__dynamic_pr_debug); | ||
457 | |||
416 | static __initdata char ddebug_setup_string[1024]; | 458 | static __initdata char ddebug_setup_string[1024]; |
417 | static __init int ddebug_setup_query(char *str) | 459 | static __init int ddebug_setup_query(char *str) |
418 | { | 460 | { |