aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-09-11 13:55:35 -0400
committerSteven Rostedt <rostedt@goodmis.org>2009-09-11 13:55:35 -0400
commit637e7e864103a7a68c1ce43ada27dfc25c0d113f (patch)
tree7ef0eadf41d79b07bc19f62b1355f7c824d781fd /kernel/trace
parent48659d31195bb76d688e99dabd816c5472fb1656 (diff)
tracing: add lock depth to entries
This patch adds the lock depth of the big kernel lock to the generic entry header. This way we can see the depth of the lock and help in removing the BKL. Example: # _------=> CPU# # / _-----=> irqs-off # | / _----=> need-resched # || / _---=> hardirq/softirq # ||| / _--=> preempt-depth # |||| /_--=> lock-depth # |||||/ delay # cmd pid |||||| time | caller # \ / |||||| \ | / <idle>-0 2.N..3 5902255250us+: lock_acquire: read rcu_read_lock <idle>-0 2.N..3 5902255253us+: lock_release: rcu_read_lock <idle>-0 2dN..3 5902255257us+: lock_acquire: xtime_lock <idle>-0 2dN..4 5902255259us : lock_acquire: clocksource_lock <idle>-0 2dN..4 5902255261us+: lock_release: clocksource_lock Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'kernel/trace')
-rw-r--r--kernel/trace/trace.c9
-rw-r--r--kernel/trace/trace_events.c5
-rw-r--r--kernel/trace/trace_functions_graph.c16
-rw-r--r--kernel/trace/trace_output.c10
4 files changed, 30 insertions, 10 deletions
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 1a37da2e8534..3b918283cf94 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -886,6 +886,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned long flags,
886 886
887 entry->preempt_count = pc & 0xff; 887 entry->preempt_count = pc & 0xff;
888 entry->pid = (tsk) ? tsk->pid : 0; 888 entry->pid = (tsk) ? tsk->pid : 0;
889 entry->lock_depth = (tsk) ? tsk->lock_depth : 0;
889 entry->flags = 890 entry->flags =
890#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT 891#ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT
891 (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | 892 (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) |
@@ -1530,10 +1531,10 @@ static void print_lat_help_header(struct seq_file *m)
1530 seq_puts(m, "# | / _----=> need-resched \n"); 1531 seq_puts(m, "# | / _----=> need-resched \n");
1531 seq_puts(m, "# || / _---=> hardirq/softirq \n"); 1532 seq_puts(m, "# || / _---=> hardirq/softirq \n");
1532 seq_puts(m, "# ||| / _--=> preempt-depth \n"); 1533 seq_puts(m, "# ||| / _--=> preempt-depth \n");
1533 seq_puts(m, "# |||| / \n"); 1534 seq_puts(m, "# |||| /_--=> lock-depth \n");
1534 seq_puts(m, "# ||||| delay \n"); 1535 seq_puts(m, "# |||||/ delay \n");
1535 seq_puts(m, "# cmd pid ||||| time | caller \n"); 1536 seq_puts(m, "# cmd pid |||||| time | caller \n");
1536 seq_puts(m, "# \\ / ||||| \\ | / \n"); 1537 seq_puts(m, "# \\ / |||||| \\ | / \n");
1537} 1538}
1538 1539
1539static void print_func_help_header(struct seq_file *m) 1540static void print_func_help_header(struct seq_file *m)
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 28d92027a93c..975f324a07e7 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -86,6 +86,7 @@ int trace_define_common_fields(struct ftrace_event_call *call)
86 __common_field(unsigned char, flags); 86 __common_field(unsigned char, flags);
87 __common_field(unsigned char, preempt_count); 87 __common_field(unsigned char, preempt_count);
88 __common_field(int, pid); 88 __common_field(int, pid);
89 __common_field(int, lock_depth);
89 90
90 return ret; 91 return ret;
91} 92}
@@ -571,11 +572,13 @@ static int trace_write_header(struct trace_seq *s)
571 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" 572 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
572 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" 573 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
573 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" 574 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
575 "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n"
574 "\n", 576 "\n",
575 FIELD(unsigned short, type), 577 FIELD(unsigned short, type),
576 FIELD(unsigned char, flags), 578 FIELD(unsigned char, flags),
577 FIELD(unsigned char, preempt_count), 579 FIELD(unsigned char, preempt_count),
578 FIELD(int, pid)); 580 FIELD(int, pid),
581 FIELD(int, lock_depth));
579} 582}
580 583
581static ssize_t 584static ssize_t
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index ee791a9650c5..48af49374384 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -368,6 +368,7 @@ static enum print_line_t
368print_graph_lat_fmt(struct trace_seq *s, struct trace_entry *entry) 368print_graph_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
369{ 369{
370 int hardirq, softirq; 370 int hardirq, softirq;
371 int ret;
371 372
372 hardirq = entry->flags & TRACE_FLAG_HARDIRQ; 373 hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
373 softirq = entry->flags & TRACE_FLAG_SOFTIRQ; 374 softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
@@ -382,6 +383,13 @@ print_graph_lat_fmt(struct trace_seq *s, struct trace_entry *entry)
382 hardirq ? 'h' : softirq ? 's' : '.')) 383 hardirq ? 'h' : softirq ? 's' : '.'))
383 return 0; 384 return 0;
384 385
386 if (entry->lock_depth < 0)
387 ret = trace_seq_putc(s, '.');
388 else
389 ret = trace_seq_printf(s, "%d", entry->lock_depth);
390 if (!ret)
391 return 0;
392
385 if (entry->preempt_count) 393 if (entry->preempt_count)
386 return trace_seq_printf(s, "%x", entry->preempt_count); 394 return trace_seq_printf(s, "%x", entry->preempt_count);
387 return trace_seq_puts(s, "."); 395 return trace_seq_puts(s, ".");
@@ -1001,8 +1009,8 @@ static void print_lat_header(struct seq_file *s)
1001 seq_printf(s, "#%.*s / _----=> need-resched \n", size, spaces); 1009 seq_printf(s, "#%.*s / _----=> need-resched \n", size, spaces);
1002 seq_printf(s, "#%.*s| / _---=> hardirq/softirq \n", size, spaces); 1010 seq_printf(s, "#%.*s| / _---=> hardirq/softirq \n", size, spaces);
1003 seq_printf(s, "#%.*s|| / _--=> preempt-depth \n", size, spaces); 1011 seq_printf(s, "#%.*s|| / _--=> preempt-depth \n", size, spaces);
1004 seq_printf(s, "#%.*s||| / \n", size, spaces); 1012 seq_printf(s, "#%.*s||| / _-=> lock-depth \n", size, spaces);
1005 seq_printf(s, "#%.*s|||| \n", size, spaces); 1013 seq_printf(s, "#%.*s|||| / \n", size, spaces);
1006} 1014}
1007 1015
1008static void print_graph_headers(struct seq_file *s) 1016static void print_graph_headers(struct seq_file *s)
@@ -1021,7 +1029,7 @@ static void print_graph_headers(struct seq_file *s)
1021 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) 1029 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
1022 seq_printf(s, " TASK/PID "); 1030 seq_printf(s, " TASK/PID ");
1023 if (lat) 1031 if (lat)
1024 seq_printf(s, "||||"); 1032 seq_printf(s, "|||||");
1025 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) 1033 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
1026 seq_printf(s, " DURATION "); 1034 seq_printf(s, " DURATION ");
1027 seq_printf(s, " FUNCTION CALLS\n"); 1035 seq_printf(s, " FUNCTION CALLS\n");
@@ -1035,7 +1043,7 @@ static void print_graph_headers(struct seq_file *s)
1035 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) 1043 if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC)
1036 seq_printf(s, " | | "); 1044 seq_printf(s, " | | ");
1037 if (lat) 1045 if (lat)
1038 seq_printf(s, "||||"); 1046 seq_printf(s, "|||||");
1039 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) 1047 if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION)
1040 seq_printf(s, " | | "); 1048 seq_printf(s, " | | ");
1041 seq_printf(s, " | | | |\n"); 1049 seq_printf(s, " | | | |\n");
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index be34a6aa7e4d..29a370a45582 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -465,6 +465,7 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
465{ 465{
466 int hardirq, softirq; 466 int hardirq, softirq;
467 char comm[TASK_COMM_LEN]; 467 char comm[TASK_COMM_LEN];
468 int ret;
468 469
469 trace_find_cmdline(entry->pid, comm); 470 trace_find_cmdline(entry->pid, comm);
470 hardirq = entry->flags & TRACE_FLAG_HARDIRQ; 471 hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
@@ -481,9 +482,16 @@ lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
481 hardirq ? 'h' : softirq ? 's' : '.')) 482 hardirq ? 'h' : softirq ? 's' : '.'))
482 return 0; 483 return 0;
483 484
485 if (entry->lock_depth < 0)
486 ret = trace_seq_putc(s, '.');
487 else
488 ret = trace_seq_printf(s, "%d", entry->lock_depth);
489 if (!ret)
490 return 0;
491
484 if (entry->preempt_count) 492 if (entry->preempt_count)
485 return trace_seq_printf(s, "%x", entry->preempt_count); 493 return trace_seq_printf(s, "%x", entry->preempt_count);
486 return trace_seq_puts(s, "."); 494 return trace_seq_putc(s, '.');
487} 495}
488 496
489static unsigned long preempt_mark_thresh = 100; 497static unsigned long preempt_mark_thresh = 100;