aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/dynamic-debug-howto.txt12
-rw-r--r--include/linux/dynamic_debug.h8
-rw-r--r--lib/dynamic_debug.c60
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
206The flags are: 206The flags are:
207 207
208f
209 Include the function name in the printed message
210l
211 Include line number in the printed message
212m
213 Include module name in the printed message
208p 214p
209 Causes a printk() message to be emitted to dmesg 215 Causes a printk() message to be emitted to dmesg
216t
217 Include thread ID in messages not generated from interrupt context
210 218
211Note the regexp ^[-+=][scp]+$ matches a flags specification. 219Note the regexp ^[-+=][flmpt]+$ matches a flags specification.
212Note also that there is no convenient syntax to remove all 220Note also that there is no convenient syntax to remove all
213the flags at once, you need to use "-psc". 221the flags at once, you need to use "-flmpt".
214 222
215 223
216Debug messages during boot process 224Debug 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)
44extern int ddebug_remove_module(const char *mod_name); 48extern int ddebug_remove_module(const char *mod_name);
49extern 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
31extern struct _ddebug __start___verbose[]; 33extern struct _ddebug __start___verbose[];
32extern struct _ddebug __stop___verbose[]; 34extern 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
68static 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 */
67static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, 77static 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
429int __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}
456EXPORT_SYMBOL(__dynamic_pr_debug);
457
416static __initdata char ddebug_setup_string[1024]; 458static __initdata char ddebug_setup_string[1024];
417static __init int ddebug_setup_query(char *str) 459static __init int ddebug_setup_query(char *str)
418{ 460{