Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Bart Van Assche and committed by
Greg Kroah-Hartman
8ba6ebf5 9b99b7f8

+68 -12
+10 -2
Documentation/dynamic-debug-howto.txt
··· 205 205 206 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 214 p 209 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 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 224 Debug messages during boot process
+7 -1
include/linux/dynamic_debug.h
··· 31 31 * writes commands to <debugfs>/dynamic_debug/control 32 32 */ 33 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 38 #define _DPRINTK_FLAGS_DEFAULT 0 35 39 unsigned int flags:8; 36 40 char enabled; ··· 46 42 47 43 #if defined(CONFIG_DYNAMIC_DEBUG) 48 44 extern int ddebug_remove_module(const char *mod_name); 45 + extern int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) 46 + __attribute__ ((format (printf, 2, 3))); 49 47 50 48 #define dynamic_pr_debug(fmt, ...) do { \ 51 49 static struct _ddebug descriptor \ ··· 56 50 { KBUILD_MODNAME, __func__, __FILE__, fmt, __LINE__, \ 57 51 _DPRINTK_FLAGS_DEFAULT }; \ 58 52 if (unlikely(descriptor.enabled)) \ 59 - printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__); \ 53 + __dynamic_pr_debug(&descriptor, pr_fmt(fmt), ##__VA_ARGS__); \ 60 54 } while (0) 61 55 62 56
+51 -9
lib/dynamic_debug.c
··· 7 7 * Copyright (C) 2008 Jason Baron <jbaron@redhat.com> 8 8 * By Greg Banks <gnb@melbourne.sgi.com> 9 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 13 #include <linux/kernel.h> ··· 28 27 #include <linux/debugfs.h> 29 28 #include <linux/slab.h> 30 29 #include <linux/jump_label.h> 30 + #include <linux/hardirq.h> 31 31 32 32 extern struct _ddebug __start___verbose[]; 33 33 extern struct _ddebug __stop___verbose[]; ··· 65 63 return tail ? tail+1 : path; 66 64 } 67 65 66 + static struct { unsigned flag:8; char opt_char; } opt_array[] = { 67 + { _DPRINTK_FLAGS_PRINT, 'p' }, 68 + { _DPRINTK_FLAGS_INCL_MODNAME, 'm' }, 69 + { _DPRINTK_FLAGS_INCL_FUNCNAME, 'f' }, 70 + { _DPRINTK_FLAGS_INCL_LINENO, 'l' }, 71 + { _DPRINTK_FLAGS_INCL_TID, 't' }, 72 + }; 73 + 68 74 /* format a string into buf[] which describes the _ddebug's flags */ 69 75 static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, 70 76 size_t maxlen) 71 77 { 72 78 char *p = buf; 79 + int i; 73 80 74 81 BUG_ON(maxlen < 4); 75 - if (dp->flags & _DPRINTK_FLAGS_PRINT) 76 - *p++ = 'p'; 82 + for (i = 0; i < ARRAY_SIZE(opt_array); ++i) 83 + if (dp->flags & opt_array[i].flag) 84 + *p++ = opt_array[i].opt_char; 77 85 if (p == buf) 78 86 *p++ = '-'; 79 87 *p = '\0'; ··· 355 343 unsigned int *maskp) 356 344 { 357 345 unsigned flags = 0; 358 - int op = '='; 346 + int op = '=', i; 359 347 360 348 switch (*str) { 361 349 case '+': ··· 370 358 printk(KERN_INFO "%s: op='%c'\n", __func__, op); 371 359 372 360 for ( ; *str ; ++str) { 373 - switch (*str) { 374 - case 'p': 375 - flags |= _DPRINTK_FLAGS_PRINT; 376 - break; 377 - default: 378 - return -EINVAL; 361 + for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { 362 + if (*str == opt_array[i].opt_char) { 363 + flags |= opt_array[i].flag; 364 + break; 365 + } 379 366 } 367 + if (i < 0) 368 + return -EINVAL; 380 369 } 381 370 if (flags == 0) 382 371 return -EINVAL; ··· 425 412 ddebug_change(&query, flags, mask); 426 413 return 0; 427 414 } 415 + 416 + int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) 417 + { 418 + va_list args; 419 + int res; 420 + 421 + BUG_ON(!descriptor); 422 + BUG_ON(!fmt); 423 + 424 + va_start(args, fmt); 425 + res = printk(KERN_DEBUG); 426 + if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) { 427 + if (in_interrupt()) 428 + res += printk(KERN_CONT "<intr> "); 429 + else 430 + res += printk(KERN_CONT "[%d] ", task_pid_vnr(current)); 431 + } 432 + if (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) 433 + res += printk(KERN_CONT "%s:", descriptor->modname); 434 + if (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) 435 + res += printk(KERN_CONT "%s:", descriptor->function); 436 + if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO) 437 + res += printk(KERN_CONT "%d ", descriptor->lineno); 438 + res += vprintk(fmt, args); 439 + va_end(args); 440 + 441 + return res; 442 + } 443 + EXPORT_SYMBOL(__dynamic_pr_debug); 428 444 429 445 static __initdata char ddebug_setup_string[1024]; 430 446 static __init int ddebug_setup_query(char *str)