diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-01-09 02:38:23 -0500 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2012-01-09 02:38:23 -0500 |
commit | da733563be5a9da26fe81d9f007262d00b846e22 (patch) | |
tree | db28291df94a2043af2123911984c5c173da4e6f /lib/dynamic_debug.c | |
parent | 6ccbcf2cb41131f8d56ef0723bf3f7c1f8486076 (diff) | |
parent | dab78d7924598ea4031663dd10db814e2e324928 (diff) |
Merge branch 'next' into for-linus
Diffstat (limited to 'lib/dynamic_debug.c')
-rw-r--r-- | lib/dynamic_debug.c | 174 |
1 files changed, 119 insertions, 55 deletions
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 75ca78f3a8c9..dcdade39e47f 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
@@ -10,11 +10,12 @@ | |||
10 | * Copyright (C) 2011 Bart Van Assche. All Rights Reserved. | 10 | * Copyright (C) 2011 Bart Van Assche. All Rights Reserved. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ | ||
14 | |||
13 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
14 | #include <linux/module.h> | 16 | #include <linux/module.h> |
15 | #include <linux/moduleparam.h> | 17 | #include <linux/moduleparam.h> |
16 | #include <linux/kallsyms.h> | 18 | #include <linux/kallsyms.h> |
17 | #include <linux/version.h> | ||
18 | #include <linux/types.h> | 19 | #include <linux/types.h> |
19 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
20 | #include <linux/proc_fs.h> | 21 | #include <linux/proc_fs.h> |
@@ -30,6 +31,8 @@ | |||
30 | #include <linux/jump_label.h> | 31 | #include <linux/jump_label.h> |
31 | #include <linux/hardirq.h> | 32 | #include <linux/hardirq.h> |
32 | #include <linux/sched.h> | 33 | #include <linux/sched.h> |
34 | #include <linux/device.h> | ||
35 | #include <linux/netdevice.h> | ||
33 | 36 | ||
34 | extern struct _ddebug __start___verbose[]; | 37 | extern struct _ddebug __start___verbose[]; |
35 | extern struct _ddebug __stop___verbose[]; | 38 | extern struct _ddebug __stop___verbose[]; |
@@ -38,7 +41,6 @@ struct ddebug_table { | |||
38 | struct list_head link; | 41 | struct list_head link; |
39 | char *mod_name; | 42 | char *mod_name; |
40 | unsigned int num_ddebugs; | 43 | unsigned int num_ddebugs; |
41 | unsigned int num_enabled; | ||
42 | struct _ddebug *ddebugs; | 44 | struct _ddebug *ddebugs; |
43 | }; | 45 | }; |
44 | 46 | ||
@@ -148,19 +150,13 @@ static void ddebug_change(const struct ddebug_query *query, | |||
148 | newflags = (dp->flags & mask) | flags; | 150 | newflags = (dp->flags & mask) | flags; |
149 | if (newflags == dp->flags) | 151 | if (newflags == dp->flags) |
150 | continue; | 152 | continue; |
151 | |||
152 | if (!newflags) | ||
153 | dt->num_enabled--; | ||
154 | else if (!dp->flags) | ||
155 | dt->num_enabled++; | ||
156 | dp->flags = newflags; | 153 | dp->flags = newflags; |
157 | if (newflags) | 154 | if (newflags) |
158 | dp->enabled = 1; | 155 | dp->enabled = 1; |
159 | else | 156 | else |
160 | dp->enabled = 0; | 157 | dp->enabled = 0; |
161 | if (verbose) | 158 | if (verbose) |
162 | printk(KERN_INFO | 159 | pr_info("changed %s:%d [%s]%s %s\n", |
163 | "ddebug: changed %s:%d [%s]%s %s\n", | ||
164 | dp->filename, dp->lineno, | 160 | dp->filename, dp->lineno, |
165 | dt->mod_name, dp->function, | 161 | dt->mod_name, dp->function, |
166 | ddebug_describe_flags(dp, flagbuf, | 162 | ddebug_describe_flags(dp, flagbuf, |
@@ -170,7 +166,7 @@ static void ddebug_change(const struct ddebug_query *query, | |||
170 | mutex_unlock(&ddebug_lock); | 166 | mutex_unlock(&ddebug_lock); |
171 | 167 | ||
172 | if (!nfound && verbose) | 168 | if (!nfound && verbose) |
173 | printk(KERN_INFO "ddebug: no matches for query\n"); | 169 | pr_info("no matches for query\n"); |
174 | } | 170 | } |
175 | 171 | ||
176 | /* | 172 | /* |
@@ -215,10 +211,10 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords) | |||
215 | 211 | ||
216 | if (verbose) { | 212 | if (verbose) { |
217 | int i; | 213 | int i; |
218 | printk(KERN_INFO "%s: split into words:", __func__); | 214 | pr_info("split into words:"); |
219 | for (i = 0 ; i < nwords ; i++) | 215 | for (i = 0 ; i < nwords ; i++) |
220 | printk(" \"%s\"", words[i]); | 216 | pr_cont(" \"%s\"", words[i]); |
221 | printk("\n"); | 217 | pr_cont("\n"); |
222 | } | 218 | } |
223 | 219 | ||
224 | return nwords; | 220 | return nwords; |
@@ -330,16 +326,15 @@ static int ddebug_parse_query(char *words[], int nwords, | |||
330 | } | 326 | } |
331 | } else { | 327 | } else { |
332 | if (verbose) | 328 | if (verbose) |
333 | printk(KERN_ERR "%s: unknown keyword \"%s\"\n", | 329 | pr_err("unknown keyword \"%s\"\n", words[i]); |
334 | __func__, words[i]); | ||
335 | return -EINVAL; | 330 | return -EINVAL; |
336 | } | 331 | } |
337 | } | 332 | } |
338 | 333 | ||
339 | if (verbose) | 334 | if (verbose) |
340 | printk(KERN_INFO "%s: q->function=\"%s\" q->filename=\"%s\" " | 335 | pr_info("q->function=\"%s\" q->filename=\"%s\" " |
341 | "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n", | 336 | "q->module=\"%s\" q->format=\"%s\" q->lineno=%u-%u\n", |
342 | __func__, query->function, query->filename, | 337 | query->function, query->filename, |
343 | query->module, query->format, query->first_lineno, | 338 | query->module, query->format, query->first_lineno, |
344 | query->last_lineno); | 339 | query->last_lineno); |
345 | 340 | ||
@@ -368,7 +363,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
368 | return -EINVAL; | 363 | return -EINVAL; |
369 | } | 364 | } |
370 | if (verbose) | 365 | if (verbose) |
371 | printk(KERN_INFO "%s: op='%c'\n", __func__, op); | 366 | pr_info("op='%c'\n", op); |
372 | 367 | ||
373 | for ( ; *str ; ++str) { | 368 | for ( ; *str ; ++str) { |
374 | for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { | 369 | for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { |
@@ -383,7 +378,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
383 | if (flags == 0) | 378 | if (flags == 0) |
384 | return -EINVAL; | 379 | return -EINVAL; |
385 | if (verbose) | 380 | if (verbose) |
386 | printk(KERN_INFO "%s: flags=0x%x\n", __func__, flags); | 381 | pr_info("flags=0x%x\n", flags); |
387 | 382 | ||
388 | /* calculate final *flagsp, *maskp according to mask and op */ | 383 | /* calculate final *flagsp, *maskp according to mask and op */ |
389 | switch (op) { | 384 | switch (op) { |
@@ -401,8 +396,7 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
401 | break; | 396 | break; |
402 | } | 397 | } |
403 | if (verbose) | 398 | if (verbose) |
404 | printk(KERN_INFO "%s: *flagsp=0x%x *maskp=0x%x\n", | 399 | pr_info("*flagsp=0x%x *maskp=0x%x\n", *flagsp, *maskp); |
405 | __func__, *flagsp, *maskp); | ||
406 | return 0; | 400 | return 0; |
407 | } | 401 | } |
408 | 402 | ||
@@ -427,40 +421,117 @@ static int ddebug_exec_query(char *query_string) | |||
427 | return 0; | 421 | return 0; |
428 | } | 422 | } |
429 | 423 | ||
424 | #define PREFIX_SIZE 64 | ||
425 | |||
426 | static int remaining(int wrote) | ||
427 | { | ||
428 | if (PREFIX_SIZE - wrote > 0) | ||
429 | return PREFIX_SIZE - wrote; | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf) | ||
434 | { | ||
435 | int pos_after_tid; | ||
436 | int pos = 0; | ||
437 | |||
438 | pos += snprintf(buf + pos, remaining(pos), "%s", KERN_DEBUG); | ||
439 | if (desc->flags & _DPRINTK_FLAGS_INCL_TID) { | ||
440 | if (in_interrupt()) | ||
441 | pos += snprintf(buf + pos, remaining(pos), "%s ", | ||
442 | "<intr>"); | ||
443 | else | ||
444 | pos += snprintf(buf + pos, remaining(pos), "[%d] ", | ||
445 | task_pid_vnr(current)); | ||
446 | } | ||
447 | pos_after_tid = pos; | ||
448 | if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME) | ||
449 | pos += snprintf(buf + pos, remaining(pos), "%s:", | ||
450 | desc->modname); | ||
451 | if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) | ||
452 | pos += snprintf(buf + pos, remaining(pos), "%s:", | ||
453 | desc->function); | ||
454 | if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO) | ||
455 | pos += snprintf(buf + pos, remaining(pos), "%d:", desc->lineno); | ||
456 | if (pos - pos_after_tid) | ||
457 | pos += snprintf(buf + pos, remaining(pos), " "); | ||
458 | if (pos >= PREFIX_SIZE) | ||
459 | buf[PREFIX_SIZE - 1] = '\0'; | ||
460 | |||
461 | return buf; | ||
462 | } | ||
463 | |||
430 | int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) | 464 | int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) |
431 | { | 465 | { |
432 | va_list args; | 466 | va_list args; |
433 | int res; | 467 | int res; |
468 | struct va_format vaf; | ||
469 | char buf[PREFIX_SIZE]; | ||
434 | 470 | ||
435 | BUG_ON(!descriptor); | 471 | BUG_ON(!descriptor); |
436 | BUG_ON(!fmt); | 472 | BUG_ON(!fmt); |
437 | 473 | ||
438 | va_start(args, fmt); | 474 | va_start(args, fmt); |
439 | res = printk(KERN_DEBUG); | 475 | vaf.fmt = fmt; |
440 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) { | 476 | vaf.va = &args; |
441 | if (in_interrupt()) | 477 | res = printk("%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf); |
442 | res += printk(KERN_CONT "<intr> "); | ||
443 | else | ||
444 | res += printk(KERN_CONT "[%d] ", task_pid_vnr(current)); | ||
445 | } | ||
446 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) | ||
447 | res += printk(KERN_CONT "%s:", descriptor->modname); | ||
448 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) | ||
449 | res += printk(KERN_CONT "%s:", descriptor->function); | ||
450 | if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO) | ||
451 | res += printk(KERN_CONT "%d ", descriptor->lineno); | ||
452 | res += vprintk(fmt, args); | ||
453 | va_end(args); | 478 | va_end(args); |
454 | 479 | ||
455 | return res; | 480 | return res; |
456 | } | 481 | } |
457 | EXPORT_SYMBOL(__dynamic_pr_debug); | 482 | EXPORT_SYMBOL(__dynamic_pr_debug); |
458 | 483 | ||
484 | int __dynamic_dev_dbg(struct _ddebug *descriptor, | ||
485 | const struct device *dev, const char *fmt, ...) | ||
486 | { | ||
487 | struct va_format vaf; | ||
488 | va_list args; | ||
489 | int res; | ||
490 | char buf[PREFIX_SIZE]; | ||
491 | |||
492 | BUG_ON(!descriptor); | ||
493 | BUG_ON(!fmt); | ||
494 | |||
495 | va_start(args, fmt); | ||
496 | vaf.fmt = fmt; | ||
497 | vaf.va = &args; | ||
498 | res = __dev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf); | ||
499 | va_end(args); | ||
500 | |||
501 | return res; | ||
502 | } | ||
503 | EXPORT_SYMBOL(__dynamic_dev_dbg); | ||
504 | |||
505 | #ifdef CONFIG_NET | ||
506 | |||
507 | int __dynamic_netdev_dbg(struct _ddebug *descriptor, | ||
508 | const struct net_device *dev, const char *fmt, ...) | ||
509 | { | ||
510 | struct va_format vaf; | ||
511 | va_list args; | ||
512 | int res; | ||
513 | char buf[PREFIX_SIZE]; | ||
514 | |||
515 | BUG_ON(!descriptor); | ||
516 | BUG_ON(!fmt); | ||
517 | |||
518 | va_start(args, fmt); | ||
519 | vaf.fmt = fmt; | ||
520 | vaf.va = &args; | ||
521 | res = __netdev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf); | ||
522 | va_end(args); | ||
523 | |||
524 | return res; | ||
525 | } | ||
526 | EXPORT_SYMBOL(__dynamic_netdev_dbg); | ||
527 | |||
528 | #endif | ||
529 | |||
459 | static __initdata char ddebug_setup_string[1024]; | 530 | static __initdata char ddebug_setup_string[1024]; |
460 | static __init int ddebug_setup_query(char *str) | 531 | static __init int ddebug_setup_query(char *str) |
461 | { | 532 | { |
462 | if (strlen(str) >= 1024) { | 533 | if (strlen(str) >= 1024) { |
463 | pr_warning("ddebug boot param string too large\n"); | 534 | pr_warn("ddebug boot param string too large\n"); |
464 | return 0; | 535 | return 0; |
465 | } | 536 | } |
466 | strcpy(ddebug_setup_string, str); | 537 | strcpy(ddebug_setup_string, str); |
@@ -488,8 +559,7 @@ static ssize_t ddebug_proc_write(struct file *file, const char __user *ubuf, | |||
488 | return -EFAULT; | 559 | return -EFAULT; |
489 | tmpbuf[len] = '\0'; | 560 | tmpbuf[len] = '\0'; |
490 | if (verbose) | 561 | if (verbose) |
491 | printk(KERN_INFO "%s: read %d bytes from userspace\n", | 562 | pr_info("read %d bytes from userspace\n", (int)len); |
492 | __func__, (int)len); | ||
493 | 563 | ||
494 | ret = ddebug_exec_query(tmpbuf); | 564 | ret = ddebug_exec_query(tmpbuf); |
495 | if (ret) | 565 | if (ret) |
@@ -552,8 +622,7 @@ static void *ddebug_proc_start(struct seq_file *m, loff_t *pos) | |||
552 | int n = *pos; | 622 | int n = *pos; |
553 | 623 | ||
554 | if (verbose) | 624 | if (verbose) |
555 | printk(KERN_INFO "%s: called m=%p *pos=%lld\n", | 625 | pr_info("called m=%p *pos=%lld\n", m, (unsigned long long)*pos); |
556 | __func__, m, (unsigned long long)*pos); | ||
557 | 626 | ||
558 | mutex_lock(&ddebug_lock); | 627 | mutex_lock(&ddebug_lock); |
559 | 628 | ||
@@ -578,8 +647,8 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos) | |||
578 | struct _ddebug *dp; | 647 | struct _ddebug *dp; |
579 | 648 | ||
580 | if (verbose) | 649 | if (verbose) |
581 | printk(KERN_INFO "%s: called m=%p p=%p *pos=%lld\n", | 650 | pr_info("called m=%p p=%p *pos=%lld\n", |
582 | __func__, m, p, (unsigned long long)*pos); | 651 | m, p, (unsigned long long)*pos); |
583 | 652 | ||
584 | if (p == SEQ_START_TOKEN) | 653 | if (p == SEQ_START_TOKEN) |
585 | dp = ddebug_iter_first(iter); | 654 | dp = ddebug_iter_first(iter); |
@@ -602,8 +671,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p) | |||
602 | char flagsbuf[8]; | 671 | char flagsbuf[8]; |
603 | 672 | ||
604 | if (verbose) | 673 | if (verbose) |
605 | printk(KERN_INFO "%s: called m=%p p=%p\n", | 674 | pr_info("called m=%p p=%p\n", m, p); |
606 | __func__, m, p); | ||
607 | 675 | ||
608 | if (p == SEQ_START_TOKEN) { | 676 | if (p == SEQ_START_TOKEN) { |
609 | seq_puts(m, | 677 | seq_puts(m, |
@@ -628,8 +696,7 @@ static int ddebug_proc_show(struct seq_file *m, void *p) | |||
628 | static void ddebug_proc_stop(struct seq_file *m, void *p) | 696 | static void ddebug_proc_stop(struct seq_file *m, void *p) |
629 | { | 697 | { |
630 | if (verbose) | 698 | if (verbose) |
631 | printk(KERN_INFO "%s: called m=%p p=%p\n", | 699 | pr_info("called m=%p p=%p\n", m, p); |
632 | __func__, m, p); | ||
633 | mutex_unlock(&ddebug_lock); | 700 | mutex_unlock(&ddebug_lock); |
634 | } | 701 | } |
635 | 702 | ||
@@ -652,7 +719,7 @@ static int ddebug_proc_open(struct inode *inode, struct file *file) | |||
652 | int err; | 719 | int err; |
653 | 720 | ||
654 | if (verbose) | 721 | if (verbose) |
655 | printk(KERN_INFO "%s: called\n", __func__); | 722 | pr_info("called\n"); |
656 | 723 | ||
657 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); | 724 | iter = kzalloc(sizeof(*iter), GFP_KERNEL); |
658 | if (iter == NULL) | 725 | if (iter == NULL) |
@@ -696,7 +763,6 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, | |||
696 | } | 763 | } |
697 | dt->mod_name = new_name; | 764 | dt->mod_name = new_name; |
698 | dt->num_ddebugs = n; | 765 | dt->num_ddebugs = n; |
699 | dt->num_enabled = 0; | ||
700 | dt->ddebugs = tab; | 766 | dt->ddebugs = tab; |
701 | 767 | ||
702 | mutex_lock(&ddebug_lock); | 768 | mutex_lock(&ddebug_lock); |
@@ -704,8 +770,7 @@ int ddebug_add_module(struct _ddebug *tab, unsigned int n, | |||
704 | mutex_unlock(&ddebug_lock); | 770 | mutex_unlock(&ddebug_lock); |
705 | 771 | ||
706 | if (verbose) | 772 | if (verbose) |
707 | printk(KERN_INFO "%u debug prints in module %s\n", | 773 | pr_info("%u debug prints in module %s\n", n, dt->mod_name); |
708 | n, dt->mod_name); | ||
709 | return 0; | 774 | return 0; |
710 | } | 775 | } |
711 | EXPORT_SYMBOL_GPL(ddebug_add_module); | 776 | EXPORT_SYMBOL_GPL(ddebug_add_module); |
@@ -727,8 +792,7 @@ int ddebug_remove_module(const char *mod_name) | |||
727 | int ret = -ENOENT; | 792 | int ret = -ENOENT; |
728 | 793 | ||
729 | if (verbose) | 794 | if (verbose) |
730 | printk(KERN_INFO "%s: removing module \"%s\"\n", | 795 | pr_info("removing module \"%s\"\n", mod_name); |
731 | __func__, mod_name); | ||
732 | 796 | ||
733 | mutex_lock(&ddebug_lock); | 797 | mutex_lock(&ddebug_lock); |
734 | list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) { | 798 | list_for_each_entry_safe(dt, nextdt, &ddebug_tables, link) { |
@@ -804,8 +868,8 @@ static int __init dynamic_debug_init(void) | |||
804 | if (ddebug_setup_string[0] != '\0') { | 868 | if (ddebug_setup_string[0] != '\0') { |
805 | ret = ddebug_exec_query(ddebug_setup_string); | 869 | ret = ddebug_exec_query(ddebug_setup_string); |
806 | if (ret) | 870 | if (ret) |
807 | pr_warning("Invalid ddebug boot param %s", | 871 | pr_warn("Invalid ddebug boot param %s", |
808 | ddebug_setup_string); | 872 | ddebug_setup_string); |
809 | else | 873 | else |
810 | pr_info("ddebug initialized with string %s", | 874 | pr_info("ddebug initialized with string %s", |
811 | ddebug_setup_string); | 875 | ddebug_setup_string); |