Commit 637e7e864103a7a68c1ce43ada27dfc25c0d113f
Committed by
Steven Rostedt
1 parent
48659d3119
Exists in
master
and in
7 other branches
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>
Showing 5 changed files with 31 additions and 10 deletions Side-by-side Diff
include/linux/ftrace_event.h
kernel/trace/trace.c
... | ... | @@ -886,6 +886,7 @@ |
886 | 886 | |
887 | 887 | entry->preempt_count = pc & 0xff; |
888 | 888 | entry->pid = (tsk) ? tsk->pid : 0; |
889 | + entry->lock_depth = (tsk) ? tsk->lock_depth : 0; | |
889 | 890 | entry->flags = |
890 | 891 | #ifdef CONFIG_TRACE_IRQFLAGS_SUPPORT |
891 | 892 | (irqs_disabled_flags(flags) ? TRACE_FLAG_IRQS_OFF : 0) | |
... | ... | @@ -1530,10 +1531,10 @@ |
1530 | 1531 | seq_puts(m, "# | / _----=> need-resched \n"); |
1531 | 1532 | seq_puts(m, "# || / _---=> hardirq/softirq \n"); |
1532 | 1533 | seq_puts(m, "# ||| / _--=> preempt-depth \n"); |
1533 | - seq_puts(m, "# |||| / \n"); | |
1534 | - seq_puts(m, "# ||||| delay \n"); | |
1535 | - seq_puts(m, "# cmd pid ||||| time | caller \n"); | |
1536 | - seq_puts(m, "# \\ / ||||| \\ | / \n"); | |
1534 | + seq_puts(m, "# |||| /_--=> lock-depth \n"); | |
1535 | + seq_puts(m, "# |||||/ delay \n"); | |
1536 | + seq_puts(m, "# cmd pid |||||| time | caller \n"); | |
1537 | + seq_puts(m, "# \\ / |||||| \\ | / \n"); | |
1537 | 1538 | } |
1538 | 1539 | |
1539 | 1540 | static void print_func_help_header(struct seq_file *m) |
kernel/trace/trace_events.c
... | ... | @@ -86,6 +86,7 @@ |
86 | 86 | __common_field(unsigned char, flags); |
87 | 87 | __common_field(unsigned char, preempt_count); |
88 | 88 | __common_field(int, pid); |
89 | + __common_field(int, lock_depth); | |
89 | 90 | |
90 | 91 | return ret; |
91 | 92 | } |
92 | 93 | |
... | ... | @@ -571,11 +572,13 @@ |
571 | 572 | "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" |
572 | 573 | "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" |
573 | 574 | "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" |
575 | + "\tfield:%s %s;\toffset:%zu;\tsize:%zu;\n" | |
574 | 576 | "\n", |
575 | 577 | FIELD(unsigned short, type), |
576 | 578 | FIELD(unsigned char, flags), |
577 | 579 | FIELD(unsigned char, preempt_count), |
578 | - FIELD(int, pid)); | |
580 | + FIELD(int, pid), | |
581 | + FIELD(int, lock_depth)); | |
579 | 582 | } |
580 | 583 | |
581 | 584 | static ssize_t |
kernel/trace/trace_functions_graph.c
... | ... | @@ -368,6 +368,7 @@ |
368 | 368 | print_graph_lat_fmt(struct trace_seq *s, struct trace_entry *entry) |
369 | 369 | { |
370 | 370 | int hardirq, softirq; |
371 | + int ret; | |
371 | 372 | |
372 | 373 | hardirq = entry->flags & TRACE_FLAG_HARDIRQ; |
373 | 374 | softirq = entry->flags & TRACE_FLAG_SOFTIRQ; |
... | ... | @@ -382,6 +383,13 @@ |
382 | 383 | hardirq ? 'h' : softirq ? 's' : '.')) |
383 | 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 | 393 | if (entry->preempt_count) |
386 | 394 | return trace_seq_printf(s, "%x", entry->preempt_count); |
387 | 395 | return trace_seq_puts(s, "."); |
... | ... | @@ -1001,8 +1009,8 @@ |
1001 | 1009 | seq_printf(s, "#%.*s / _----=> need-resched \n", size, spaces); |
1002 | 1010 | seq_printf(s, "#%.*s| / _---=> hardirq/softirq \n", size, spaces); |
1003 | 1011 | seq_printf(s, "#%.*s|| / _--=> preempt-depth \n", size, spaces); |
1004 | - seq_printf(s, "#%.*s||| / \n", size, spaces); | |
1005 | - seq_printf(s, "#%.*s|||| \n", size, spaces); | |
1012 | + seq_printf(s, "#%.*s||| / _-=> lock-depth \n", size, spaces); | |
1013 | + seq_printf(s, "#%.*s|||| / \n", size, spaces); | |
1006 | 1014 | } |
1007 | 1015 | |
1008 | 1016 | static void print_graph_headers(struct seq_file *s) |
... | ... | @@ -1021,7 +1029,7 @@ |
1021 | 1029 | if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) |
1022 | 1030 | seq_printf(s, " TASK/PID "); |
1023 | 1031 | if (lat) |
1024 | - seq_printf(s, "||||"); | |
1032 | + seq_printf(s, "|||||"); | |
1025 | 1033 | if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) |
1026 | 1034 | seq_printf(s, " DURATION "); |
1027 | 1035 | seq_printf(s, " FUNCTION CALLS\n"); |
... | ... | @@ -1035,7 +1043,7 @@ |
1035 | 1043 | if (tracer_flags.val & TRACE_GRAPH_PRINT_PROC) |
1036 | 1044 | seq_printf(s, " | | "); |
1037 | 1045 | if (lat) |
1038 | - seq_printf(s, "||||"); | |
1046 | + seq_printf(s, "|||||"); | |
1039 | 1047 | if (tracer_flags.val & TRACE_GRAPH_PRINT_DURATION) |
1040 | 1048 | seq_printf(s, " | | "); |
1041 | 1049 | seq_printf(s, " | | | |\n"); |
kernel/trace/trace_output.c
... | ... | @@ -465,6 +465,7 @@ |
465 | 465 | { |
466 | 466 | int hardirq, softirq; |
467 | 467 | char comm[TASK_COMM_LEN]; |
468 | + int ret; | |
468 | 469 | |
469 | 470 | trace_find_cmdline(entry->pid, comm); |
470 | 471 | hardirq = entry->flags & TRACE_FLAG_HARDIRQ; |
471 | 472 | |
... | ... | @@ -481,9 +482,16 @@ |
481 | 482 | hardirq ? 'h' : softirq ? 's' : '.')) |
482 | 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 | 492 | if (entry->preempt_count) |
485 | 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 | |
489 | 497 | static unsigned long preempt_mark_thresh = 100; |