提交 4a7c7197 编写于 作者: I Ingo Molnar 提交者: Linus Torvalds

[PATCH] lockdep: stacktrace subsystem, i386 support

Framework to generate and save stacktraces quickly, without printing anything
to the console.  i386 support.
Signed-off-by: NIngo Molnar <mingo@elte.hu>
Signed-off-by: NArjan van de Ven <arjan@linux.intel.com>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 cbbd1fa7
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -18,6 +18,10 @@ config GENERIC_TIME
bool
default y
config STACKTRACE_SUPPORT
bool
default y
config SEMAPHORE_SLEEPERS
bool
default y
......
......@@ -9,6 +9,7 @@ obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \
pci-dma.o i386_ksyms.o i387.o bootflag.o \
quirks.o i8237.o topology.o alternative.o i8253.o tsc.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += cpu/
obj-y += acpi/
obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o
......
/*
* arch/i386/kernel/stacktrace.c
*
* Stack trace management functions
*
* Copyright (C) 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
*/
#include <linux/sched.h>
#include <linux/stacktrace.h>
static inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
{
return p > (void *)tinfo &&
p < (void *)tinfo + THREAD_SIZE - 3;
}
/*
* Save stack-backtrace addresses into a stack_trace buffer:
*/
static inline unsigned long
save_context_stack(struct stack_trace *trace, unsigned int skip,
struct thread_info *tinfo, unsigned long *stack,
unsigned long ebp)
{
unsigned long addr;
#ifdef CONFIG_FRAME_POINTER
while (valid_stack_ptr(tinfo, (void *)ebp)) {
addr = *(unsigned long *)(ebp + 4);
if (!skip)
trace->entries[trace->nr_entries++] = addr;
else
skip--;
if (trace->nr_entries >= trace->max_entries)
break;
/*
* break out of recursive entries (such as
* end_of_stack_stop_unwind_function):
*/
if (ebp == *(unsigned long *)ebp)
break;
ebp = *(unsigned long *)ebp;
}
#else
while (valid_stack_ptr(tinfo, stack)) {
addr = *stack++;
if (__kernel_text_address(addr)) {
if (!skip)
trace->entries[trace->nr_entries++] = addr;
else
skip--;
if (trace->nr_entries >= trace->max_entries)
break;
}
}
#endif
return ebp;
}
/*
* Save stack-backtrace addresses into a stack_trace buffer.
* If all_contexts is set, all contexts (hardirq, softirq and process)
* are saved. If not set then only the current context is saved.
*/
void save_stack_trace(struct stack_trace *trace,
struct task_struct *task, int all_contexts,
unsigned int skip)
{
unsigned long ebp;
unsigned long *stack = &ebp;
WARN_ON(trace->nr_entries || !trace->max_entries);
if (!task || task == current) {
/* Grab ebp right from our regs: */
asm ("movl %%ebp, %0" : "=r" (ebp));
} else {
/* ebp is the last reg pushed by switch_to(): */
ebp = *(unsigned long *) task->thread.esp;
}
while (1) {
struct thread_info *context = (struct thread_info *)
((unsigned long)stack & (~(THREAD_SIZE - 1)));
ebp = save_context_stack(trace, skip, context, stack, ebp);
stack = (unsigned long *)context->previous_esp;
if (!all_contexts || !stack ||
trace->nr_entries >= trace->max_entries)
break;
trace->entries[trace->nr_entries++] = ULONG_MAX;
if (trace->nr_entries >= trace->max_entries)
break;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部