diff options
-rw-r--r-- | Documentation/dynamic-debug-howto.txt | 12 | ||||
-rw-r--r-- | include/linux/dynamic_debug.h | 8 | ||||
-rw-r--r-- | lib/dynamic_debug.c | 60 |
3 files changed, 68 insertions, 12 deletions
diff --git a/Documentation/dynamic-debug-howto.txt b/Documentation/dynamic-debug-howto.txt index 58ea64a96165..e6c4b757025b 100644 --- a/Documentation/dynamic-debug-howto.txt +++ b/Documentation/dynamic-debug-howto.txt | |||
@@ -205,12 +205,20 @@ of the characters: | |||
205 | 205 | ||
206 | The flags are: | 206 | The flags are: |
207 | 207 | ||
208 | f | ||
209 | Include the function name in the printed message | ||
210 | l | ||
211 | Include line number in the printed message | ||
212 | m | ||
213 | Include module name in the printed message | ||
208 | p | 214 | p |
209 | Causes a printk() message to be emitted to dmesg | 215 | Causes a printk() message to be emitted to dmesg |
216 | t | ||
217 | Include thread ID in messages not generated from interrupt context | ||
210 | 218 | ||
211 | Note the regexp ^[-+=][scp]+$ matches a flags specification. | 219 | Note the regexp ^[-+=][flmpt]+$ matches a flags specification. |
212 | Note also that there is no convenient syntax to remove all | 220 | Note also that there is no convenient syntax to remove all |
213 | the flags at once, you need to use "-psc". | 221 | the flags at once, you need to use "-flmpt". |
214 | 222 | ||
215 | 223 | ||
216 | Debug messages during boot process | 224 | Debug messages during boot process |
diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index 1c70028f81f9..0c9653f11c18 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h | |||
@@ -31,6 +31,10 @@ struct _ddebug { | |||
31 | * writes commands to <debugfs>/dynamic_debug/control | 31 | * writes commands to <debugfs>/dynamic_debug/control |
32 | */ | 32 | */ |
33 | #define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */ | 33 | #define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */ |
34 | #define _DPRINTK_FLAGS_INCL_MODNAME (1<<1) | ||
35 | #define _DPRINTK_FLAGS_INCL_FUNCNAME (1<<2) | ||
36 | #define _DPRINTK_FLAGS_INCL_LINENO (1<<3) | ||
37 | #define _DPRINTK_FLAGS_INCL_TID (1<<4) | ||
34 | #define _DPRINTK_FLAGS_DEFAULT 0 | 38 | #define _DPRINTK_FLAGS_DEFAULT 0 |
35 | unsigned int flags:8; | 39 | unsigned int flags:8; |
36 | char enabled; | 40 | char enabled; |
@@ -42,6 +46,8 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, | |||
42 | 46 | ||
43 | #if defined(CONFIG_DYNAMIC_DEBUG) | 47 | #if defined(CONFIG_DYNAMIC_DEBUG) |
44 | extern int ddebug_remove_module(const char *mod_name); | 48 | extern int ddebug_remove_module(const char *mod_name); |
49 | extern int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) | ||
50 | __attribute__ ((format (printf, 2, 3))); | ||
45 | 51 | ||
46 | #define dynamic_pr_debug(fmt, ...) do { \ | 52 | #define dynamic_pr_debug(fmt, ...) do { \ |
47 | static struct _ddebug descriptor \ | 53 | static struct _ddebug descriptor \ |
@@ -50,7 +56,7 @@ extern int ddebug_remove_module(const char *mod_name); | |||
50 | { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ | 56 | { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ |
51 | _DPRINTK_FLAGS_DEFAULT }; \ | 57 | _DPRINTK_FLAGS_DEFAULT }; \ |
52 | if (unlikely(descriptor.enabled)) \ | 58 | if (unlikely(descriptor.enabled)) \ |
53 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ | 59 | __dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \ |
54 | } while (0) | 60 | } while (0) |
55 | 61 | ||
56 | 62 | ||
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 | { |