Commit 8ba6ebf5 authored by Bart Van Assche's avatar Bart Van Assche Committed by Greg Kroah-Hartman

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: default avatarBart Van Assche <bvanassche@acm.org>
Cc: Greg Banks <gnb@fmeh.org>
Cc: Konrad Rzeszutek Wilk <konrad@darnok.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 9b99b7f8
...@@ -205,12 +205,20 @@ of the characters: ...@@ -205,12 +205,20 @@ of the characters:
The flags are: The flags are:
f
Include the function name in the printed message
l
Include line number in the printed message
m
Include module name in the printed message
p p
Causes a printk() message to be emitted to dmesg Causes a printk() message to be emitted to dmesg
t
Include thread ID in messages not generated from interrupt context
Note the regexp ^[-+=][scp]+$ matches a flags specification. Note the regexp ^[-+=][flmpt]+$ matches a flags specification.
Note also that there is no convenient syntax to remove all Note also that there is no convenient syntax to remove all
the flags at once, you need to use "-psc". the flags at once, you need to use "-flmpt".
Debug messages during boot process Debug messages during boot process
......
...@@ -31,6 +31,10 @@ struct _ddebug { ...@@ -31,6 +31,10 @@ struct _ddebug {
* writes commands to <debugfs>/dynamic_debug/control * writes commands to <debugfs>/dynamic_debug/control
*/ */
#define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */ #define _DPRINTK_FLAGS_PRINT (1<<0) /* printk() a message using the format */
#define _DPRINTK_FLAGS_INCL_MODNAME (1<<1)
#define _DPRINTK_FLAGS_INCL_FUNCNAME (1<<2)
#define _DPRINTK_FLAGS_INCL_LINENO (1<<3)
#define _DPRINTK_FLAGS_INCL_TID (1<<4)
#define _DPRINTK_FLAGS_DEFAULT 0 #define _DPRINTK_FLAGS_DEFAULT 0
unsigned int flags:8; unsigned int flags:8;
char enabled; char enabled;
...@@ -42,6 +46,8 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, ...@@ -42,6 +46,8 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n,
#if defined(CONFIG_DYNAMIC_DEBUG) #if defined(CONFIG_DYNAMIC_DEBUG)
extern int ddebug_remove_module(const char *mod_name); extern int ddebug_remove_module(const char *mod_name);
extern int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
#define dynamic_pr_debug(fmt, ...) do { \ #define dynamic_pr_debug(fmt, ...) do { \
static struct _ddebug descriptor \ static struct _ddebug descriptor \
...@@ -50,7 +56,7 @@ extern int ddebug_remove_module(const char *mod_name); ...@@ -50,7 +56,7 @@ extern int ddebug_remove_module(const char *mod_name);
{ KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \
_DPRINTK_FLAGS_DEFAULT }; \ _DPRINTK_FLAGS_DEFAULT }; \
if (unlikely(descriptor.enabled)) \ if (unlikely(descriptor.enabled)) \
printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ __dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \
} while (0) } while (0)
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Copyright (C) 2008 Jason Baron <jbaron@redhat.com> * Copyright (C) 2008 Jason Baron <jbaron@redhat.com>
* By Greg Banks <gnb@melbourne.sgi.com> * By Greg Banks <gnb@melbourne.sgi.com>
* Copyright (c) 2008 Silicon Graphics Inc. All Rights Reserved. * Copyright (c) 2008 Silicon Graphics Inc. All Rights Reserved.
* Copyright (C) 2011 Bart Van Assche. All Rights Reserved.
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -27,6 +28,7 @@ ...@@ -27,6 +28,7 @@
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/jump_label.h> #include <linux/jump_label.h>
#include <linux/hardirq.h>
extern struct _ddebug __start___verbose[]; extern struct _ddebug __start___verbose[];
extern struct _ddebug __stop___verbose[]; extern struct _ddebug __stop___verbose[];
...@@ -63,15 +65,25 @@ static inline const char *basename(const char *path) ...@@ -63,15 +65,25 @@ static inline const char *basename(const char *path)
return tail ? tail+1 : path; return tail ? tail+1 : path;
} }
static struct { unsigned flag:8; char opt_char; } opt_array[] = {
{ _DPRINTK_FLAGS_PRINT, 'p' },
{ _DPRINTK_FLAGS_INCL_MODNAME, 'm' },
{ _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' },
{ _DPRINTK_FLAGS_INCL_LINENO, 'l' },
{ _DPRINTK_FLAGS_INCL_TID, 't' },
};
/* format a string into buf[] which describes the _ddebug's flags */ /* format a string into buf[] which describes the _ddebug's flags */
static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, static char *ddebug_describe_flags(struct _ddebug *dp, char *buf,
size_t maxlen) size_t maxlen)
{ {
char *p = buf; char *p = buf;
int i;
BUG_ON(maxlen < 4); BUG_ON(maxlen < 4);
if (dp->flags & _DPRINTK_FLAGS_PRINT) for (i = 0; i < ARRAY_SIZE(opt_array); ++i)
*p++ = 'p'; if (dp->flags & opt_array[i].flag)
*p++ = opt_array[i].opt_char;
if (p == buf) if (p == buf)
*p++ = '-'; *p++ = '-';
*p = '\0'; *p = '\0';
...@@ -343,7 +355,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, ...@@ -343,7 +355,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
unsigned int *maskp) unsigned int *maskp)
{ {
unsigned flags = 0; unsigned flags = 0;
int op = '='; int op = '=', i;
switch (*str) { switch (*str) {
case '+': case '+':
...@@ -358,13 +370,14 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, ...@@ -358,13 +370,14 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp,
printk(KERN_INFO "%s: op='%c'\n", __func__, op); printk(KERN_INFO "%s: op='%c'\n", __func__, op);
for ( ; *str ; ++str) { for ( ; *str ; ++str) {
switch (*str) { for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) {
case 'p': if (*str == opt_array[i].opt_char) {
flags |= _DPRINTK_FLAGS_PRINT; flags |= opt_array[i].flag;
break; break;
default: }
return -EINVAL;
} }
if (i < 0)
return -EINVAL;
} }
if (flags == 0) if (flags == 0)
return -EINVAL; return -EINVAL;
...@@ -413,6 +426,35 @@ static int ddebug_exec_query(char *query_string) ...@@ -413,6 +426,35 @@ static int ddebug_exec_query(char *query_string)
return 0; return 0;
} }
int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
{
va_list args;
int res;
BUG_ON(!descriptor);
BUG_ON(!fmt);
va_start(args, fmt);
res = printk(KERN_DEBUG);
if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) {
if (in_interrupt())
res += printk(KERN_CONT "<intr> ");
else
res += printk(KERN_CONT "[%d] ", task_pid_vnr(current));
}
if (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME)
res += printk(KERN_CONT "%s:", descriptor->modname);
if (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
res += printk(KERN_CONT "%s:", descriptor->function);
if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO)
res += printk(KERN_CONT "%d ", descriptor->lineno);
res += vprintk(fmt, args);
va_end(args);
return res;
}
EXPORT_SYMBOL(__dynamic_pr_debug);
static __initdata char ddebug_setup_string[1024]; static __initdata char ddebug_setup_string[1024];
static __init int ddebug_setup_query(char *str) static __init int ddebug_setup_query(char *str)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment