diff options
Diffstat (limited to 'arch/x86/kernel/stacktrace.c')
| -rw-r--r-- | arch/x86/kernel/stacktrace.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/arch/x86/kernel/stacktrace.c b/arch/x86/kernel/stacktrace.c index 6fa6cf036c70..55771fd7e545 100644 --- a/arch/x86/kernel/stacktrace.c +++ b/arch/x86/kernel/stacktrace.c | |||
| @@ -33,6 +33,19 @@ static void save_stack_address(void *data, unsigned long addr) | |||
| 33 | trace->entries[trace->nr_entries++] = addr; | 33 | trace->entries[trace->nr_entries++] = addr; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | static void save_stack_address_nosched(void *data, unsigned long addr) | ||
| 37 | { | ||
| 38 | struct stack_trace *trace = (struct stack_trace *)data; | ||
| 39 | if (in_sched_functions(addr)) | ||
| 40 | return; | ||
| 41 | if (trace->skip > 0) { | ||
| 42 | trace->skip--; | ||
| 43 | return; | ||
| 44 | } | ||
| 45 | if (trace->nr_entries < trace->max_entries) | ||
| 46 | trace->entries[trace->nr_entries++] = addr; | ||
| 47 | } | ||
| 48 | |||
| 36 | static const struct stacktrace_ops save_stack_ops = { | 49 | static const struct stacktrace_ops save_stack_ops = { |
| 37 | .warning = save_stack_warning, | 50 | .warning = save_stack_warning, |
| 38 | .warning_symbol = save_stack_warning_symbol, | 51 | .warning_symbol = save_stack_warning_symbol, |
| @@ -40,6 +53,13 @@ static const struct stacktrace_ops save_stack_ops = { | |||
| 40 | .address = save_stack_address, | 53 | .address = save_stack_address, |
| 41 | }; | 54 | }; |
| 42 | 55 | ||
| 56 | static const struct stacktrace_ops save_stack_ops_nosched = { | ||
| 57 | .warning = save_stack_warning, | ||
| 58 | .warning_symbol = save_stack_warning_symbol, | ||
| 59 | .stack = save_stack_stack, | ||
| 60 | .address = save_stack_address_nosched, | ||
| 61 | }; | ||
| 62 | |||
| 43 | /* | 63 | /* |
| 44 | * Save stack-backtrace addresses into a stack_trace buffer. | 64 | * Save stack-backtrace addresses into a stack_trace buffer. |
| 45 | */ | 65 | */ |
| @@ -50,3 +70,10 @@ void save_stack_trace(struct stack_trace *trace) | |||
| 50 | trace->entries[trace->nr_entries++] = ULONG_MAX; | 70 | trace->entries[trace->nr_entries++] = ULONG_MAX; |
| 51 | } | 71 | } |
| 52 | EXPORT_SYMBOL(save_stack_trace); | 72 | EXPORT_SYMBOL(save_stack_trace); |
| 73 | |||
| 74 | void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) | ||
| 75 | { | ||
| 76 | dump_trace(tsk, NULL, NULL, &save_stack_ops_nosched, trace); | ||
| 77 | if (trace->nr_entries < trace->max_entries) | ||
| 78 | trace->entries[trace->nr_entries++] = ULONG_MAX; | ||
| 79 | } | ||
