| From: Steven Rostedt <srostedt@redhat.com> |
| Date: Thu, 19 Apr 2012 10:31:47 -0400 |
| Subject: [PATCH] tracing: Fix stacktrace of latency tracers (irqsoff and |
| friends) |
| |
| commit db4c75cbebd7e5910cd3bcb6790272fcc3042857 upstream. |
| |
| While debugging a latency with someone on IRC (mirage335) on #linux-rt (OFTC), |
| we discovered that the stacktrace output of the latency tracers |
| (preemptirqsoff) was empty. |
| |
| This bug was caused by the creation of the dynamic length stack trace |
| again (like commit 12b5da3 "tracing: Fix ent_size in trace output" was). |
| |
| This bug is caused by the latency tracers requiring the next event |
| to determine the time between the current event and the next. But by |
| grabbing the next event, the iter->ent_size is set to the next event |
| instead of the current one. As the stacktrace event is the last event, |
| this makes the ent_size zero and causes nothing to be printed for |
| the stack trace. The dynamic stacktrace uses the ent_size to determine |
| how much of the stack can be printed. The ent_size of zero means |
| no stack. |
| |
| The simple fix is to save the iter->ent_size before finding the next event. |
| |
| Note, mirage335 asked to remain anonymous from LKML and git, so I will |
| not add the Reported-by and Tested-by tags, even though he did report |
| the issue and tested the fix. |
| |
| Signed-off-by: Steven Rostedt <rostedt@goodmis.org> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| kernel/trace/trace_output.c | 5 +++++ |
| 1 file changed, 5 insertions(+) |
| |
| diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c |
| index 859fae6..df611a0 100644 |
| --- a/kernel/trace/trace_output.c |
| +++ b/kernel/trace/trace_output.c |
| @@ -652,6 +652,8 @@ int trace_print_lat_context(struct trace_iterator *iter) |
| { |
| u64 next_ts; |
| int ret; |
| + /* trace_find_next_entry will reset ent_size */ |
| + int ent_size = iter->ent_size; |
| struct trace_seq *s = &iter->seq; |
| struct trace_entry *entry = iter->ent, |
| *next_entry = trace_find_next_entry(iter, NULL, |
| @@ -660,6 +662,9 @@ int trace_print_lat_context(struct trace_iterator *iter) |
| unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start); |
| unsigned long rel_usecs; |
| |
| + /* Restore the original ent_size */ |
| + iter->ent_size = ent_size; |
| + |
| if (!next_entry) |
| next_ts = iter->ts; |
| rel_usecs = ns2usecs(next_ts - iter->ts); |
| -- |
| 1.7.10 |
| |