]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/kernel/dumpstack.c
Merge commit 'origin/master' into next
[linux-2.6-omap-h63xx.git] / arch / x86 / kernel / dumpstack.c
index 5962176dfabb5e66663bd6576e364839c577bd96..dd2130b0fb3e4ac183e1d62a979242db6b78f22e 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/kdebug.h>
 #include <linux/module.h>
 #include <linux/ptrace.h>
+#include <linux/ftrace.h>
 #include <linux/kexec.h>
 #include <linux/bug.h>
 #include <linux/nmi.h>
@@ -30,6 +31,37 @@ void printk_address(unsigned long address, int reliable)
                        reliable ? "" : "? ", (void *) address);
 }
 
+#ifdef CONFIG_FUNCTION_GRAPH_TRACER
+static void
+print_ftrace_graph_addr(unsigned long addr, void *data,
+                       const struct stacktrace_ops *ops,
+                       struct thread_info *tinfo, int *graph)
+{
+       struct task_struct *task = tinfo->task;
+       unsigned long ret_addr;
+       int index = task->curr_ret_stack;
+
+       if (addr != (unsigned long)return_to_handler)
+               return;
+
+       if (!task->ret_stack || index < *graph)
+               return;
+
+       index -= *graph;
+       ret_addr = task->ret_stack[index].ret;
+
+       ops->address(data, ret_addr, 1);
+
+       (*graph)++;
+}
+#else
+static inline void
+print_ftrace_graph_addr(unsigned long addr, void *data,
+                       const struct stacktrace_ops *ops,
+                       struct thread_info *tinfo, int *graph)
+{ }
+#endif
+
 /*
  * x86-64 can have up to three kernel stacks:
  * process stack
@@ -54,7 +86,7 @@ unsigned long
 print_context_stack(struct thread_info *tinfo,
                unsigned long *stack, unsigned long bp,
                const struct stacktrace_ops *ops, void *data,
-               unsigned long *end)
+               unsigned long *end, int *graph)
 {
        struct stack_frame *frame = (struct stack_frame *)bp;
 
@@ -68,8 +100,9 @@ print_context_stack(struct thread_info *tinfo,
                                frame = frame->next_frame;
                                bp = (unsigned long) frame;
                        } else {
-                               ops->address(data, addr, bp == 0);
+                               ops->address(data, addr, 0);
                        }
+                       print_ftrace_graph_addr(addr, data, ops, tinfo, graph);
                }
                stack++;
        }