aboutsummaryrefslogtreecommitdiffstats
path: root/lib/dynamic_debug.c
diff options
context:
space:
mode:
authorJason Baron <jbaron@redhat.com>2011-10-04 17:13:19 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-10-18 14:22:00 -0400
commit431625dac14de7152235f2f9934d70a9b0f9df83 (patch)
tree8c08388a455e5fba84596f90942c756765967b47 /lib/dynamic_debug.c
parentbd22c01e845ad22a89ae25005b38d28e6690c27a (diff)
dynamic_debug: use a single printk() to emit messages
We were using KERN_CONT to combine messages with their prefix. However, KERN_CONT is not smp safe, in the sense that it can interleave messages. This interleaving can result in printks coming out at the wrong loglevel. With the high frequency of printks that dynamic debug can produce this is not desirable. So make dynamic_emit_prefix() fill a char buf[64] instead of doing a printk directly. If we enable printing out of function, module, line, or pid info, they are placed in this 64 byte buffer. In my testing 64 bytes was enough size to fulfill all requests. Even if it's not, we can match up the printk itself to see where it's from, so to me this is no big deal. [akpm@linux-foundation.org: convert dangerous macro to C] Signed-off-by: Jason Baron <jbaron@redhat.com> Cc: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Andrew Morton <akpm@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'lib/dynamic_debug.c')
-rw-r--r--lib/dynamic_debug.c80
1 files changed, 41 insertions, 39 deletions
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 198d2afe18ed..edec78052333 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -422,52 +422,60 @@ static int ddebug_exec_query(char *query_string)
422 return 0; 422 return 0;
423} 423}
424 424
425static int dynamic_emit_prefix(const struct _ddebug *descriptor) 425#define PREFIX_SIZE 64
426
427static int remaining(int wrote)
428{
429 if (PREFIX_SIZE - wrote > 0)
430 return PREFIX_SIZE - wrote;
431 return 0;
432}
433
434static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
426{ 435{
427 char tid[sizeof(int) + sizeof(int)/2 + 4]; 436 int pos_after_tid;
428 char lineno[sizeof(int) + sizeof(int)/2]; 437 int pos = 0;
429 438
430 if (descriptor->flags & _DPRINTK_FLAGS_INCL_TID) { 439 pos += snprintf(buf + pos, remaining(pos), "%s", KERN_DEBUG);
440 if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
431 if (in_interrupt()) 441 if (in_interrupt())
432 snprintf(tid, sizeof(tid), "%s", "<intr> "); 442 pos += snprintf(buf + pos, remaining(pos), "%s ",
443 "<intr>");
433 else 444 else
434 snprintf(tid, sizeof(tid), "[%d] ", 445 pos += snprintf(buf + pos, remaining(pos), "[%d] ",
435 task_pid_vnr(current)); 446 task_pid_vnr(current));
436 } else {
437 tid[0] = 0;
438 } 447 }
448 pos_after_tid = pos;
449 if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
450 pos += snprintf(buf + pos, remaining(pos), "%s:",
451 desc->modname);
452 if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
453 pos += snprintf(buf + pos, remaining(pos), "%s:",
454 desc->function);
455 if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
456 pos += snprintf(buf + pos, remaining(pos), "%d:", desc->lineno);
457 if (pos - pos_after_tid)
458 pos += snprintf(buf + pos, remaining(pos), " ");
459 if (pos >= PREFIX_SIZE)
460 buf[PREFIX_SIZE - 1] = '\0';
439 461
440 if (descriptor->flags & _DPRINTK_FLAGS_INCL_LINENO) 462 return buf;
441 snprintf(lineno, sizeof(lineno), "%d", descriptor->lineno);
442 else
443 lineno[0] = 0;
444
445 return printk(KERN_DEBUG "%s%s%s%s%s%s",
446 tid,
447 (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) ?
448 descriptor->modname : "",
449 (descriptor->flags & _DPRINTK_FLAGS_INCL_MODNAME) ?
450 ":" : "",
451 (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) ?
452 descriptor->function : "",
453 (descriptor->flags & _DPRINTK_FLAGS_INCL_FUNCNAME) ?
454 ":" : "",
455 lineno);
456} 463}
457 464
458int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...) 465int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
459{ 466{
460 va_list args; 467 va_list args;
461 int res; 468 int res;
469 struct va_format vaf;
470 char buf[PREFIX_SIZE];
462 471
463 BUG_ON(!descriptor); 472 BUG_ON(!descriptor);
464 BUG_ON(!fmt); 473 BUG_ON(!fmt);
465 474
466 va_start(args, fmt); 475 va_start(args, fmt);
467 476 vaf.fmt = fmt;
468 res = dynamic_emit_prefix(descriptor); 477 vaf.va = &args;
469 res += vprintk(fmt, args); 478 res = printk("%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
470
471 va_end(args); 479 va_end(args);
472 480
473 return res; 481 return res;
@@ -480,18 +488,15 @@ int __dynamic_dev_dbg(struct _ddebug *descriptor,
480 struct va_format vaf; 488 struct va_format vaf;
481 va_list args; 489 va_list args;
482 int res; 490 int res;
491 char buf[PREFIX_SIZE];
483 492
484 BUG_ON(!descriptor); 493 BUG_ON(!descriptor);
485 BUG_ON(!fmt); 494 BUG_ON(!fmt);
486 495
487 va_start(args, fmt); 496 va_start(args, fmt);
488
489 vaf.fmt = fmt; 497 vaf.fmt = fmt;
490 vaf.va = &args; 498 vaf.va = &args;
491 499 res = __dev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf);
492 res = dynamic_emit_prefix(descriptor);
493 res += __dev_printk(KERN_CONT, dev, &vaf);
494
495 va_end(args); 500 va_end(args);
496 501
497 return res; 502 return res;
@@ -504,18 +509,15 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor,
504 struct va_format vaf; 509 struct va_format vaf;
505 va_list args; 510 va_list args;
506 int res; 511 int res;
512 char buf[PREFIX_SIZE];
507 513
508 BUG_ON(!descriptor); 514 BUG_ON(!descriptor);
509 BUG_ON(!fmt); 515 BUG_ON(!fmt);
510 516
511 va_start(args, fmt); 517 va_start(args, fmt);
512
513 vaf.fmt = fmt; 518 vaf.fmt = fmt;
514 vaf.va = &args; 519 vaf.va = &args;
515 520 res = __netdev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf);
516 res = dynamic_emit_prefix(descriptor);
517 res += __netdev_printk(KERN_CONT, dev, &vaf);
518
519 va_end(args); 521 va_end(args);
520 522
521 return res; 523 return res;