--- /dev/null
+#ifndef __LINUX_STACKTRACE_H
+#define __LINUX_STACKTRACE_H
+
+#ifdef CONFIG_STACKTRACE
+struct stack_trace {
+       unsigned int nr_entries, max_entries;
+       unsigned long *entries;
+};
+
+extern void save_stack_trace(struct stack_trace *trace,
+                            struct task_struct *task, int all_contexts,
+                            unsigned int skip);
+
+extern void print_stack_trace(struct stack_trace *trace, int spaces);
+#else
+# define save_stack_trace(trace, task, all, skip)      do { } while (0)
+# define print_stack_trace(trace)                      do { } while (0)
+#endif
+
+#endif
 
            kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
            hrtimer.o
 
+obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-y += time/
 obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
 obj-$(CONFIG_FUTEX) += futex.o
 
--- /dev/null
+/*
+ * kernel/stacktrace.c
+ *
+ * Stack trace management functions
+ *
+ *  Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ */
+#include <linux/sched.h>
+#include <linux/kallsyms.h>
+#include <linux/stacktrace.h>
+
+void print_stack_trace(struct stack_trace *trace, int spaces)
+{
+       int i, j;
+
+       for (i = 0; i < trace->nr_entries; i++) {
+               unsigned long ip = trace->entries[i];
+
+               for (j = 0; j < spaces + 1; j++)
+                       printk(" ");
+               print_ip_sym(ip);
+       }
+}
+
 
 
 config DEBUG_PREEMPT
        bool "Debug preemptible kernel"
-       depends on DEBUG_KERNEL && PREEMPT
+       depends on DEBUG_KERNEL && PREEMPT && TRACE_IRQFLAGS_SUPPORT
        default y
        help
          If you say Y here then the kernel will use a debug variant of the
          If you say Y here, various routines which may sleep will become very
          noisy if they are called with a spinlock held.
 
+config STACKTRACE
+       bool
+       depends on STACKTRACE_SUPPORT
+
 config DEBUG_KOBJECT
        bool "kobject debugging"
        depends on DEBUG_KERNEL