]>
Commit | Line | Data |
---|---|---|
5bdc9b44 | 1 | /* |
5bdc9b44 HC |
2 | * Stack trace management functions |
3 | * | |
a53c8fab | 4 | * Copyright IBM Corp. 2006 |
5bdc9b44 HC |
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> |
6 | */ | |
7 | ||
8 | #include <linux/sched.h> | |
b17b0153 | 9 | #include <linux/sched/debug.h> |
5bdc9b44 HC |
10 | #include <linux/stacktrace.h> |
11 | #include <linux/kallsyms.h> | |
3994a52b | 12 | #include <linux/export.h> |
5bdc9b44 | 13 | |
758d39eb | 14 | static int __save_address(void *data, unsigned long address, int nosched) |
5bdc9b44 | 15 | { |
758d39eb | 16 | struct stack_trace *trace = data; |
5bdc9b44 | 17 | |
758d39eb HC |
18 | if (nosched && in_sched_functions(address)) |
19 | return 0; | |
20 | if (trace->skip > 0) { | |
21 | trace->skip--; | |
22 | return 0; | |
5bdc9b44 | 23 | } |
758d39eb HC |
24 | if (trace->nr_entries < trace->max_entries) { |
25 | trace->entries[trace->nr_entries++] = address; | |
26 | return 0; | |
27 | } | |
28 | return 1; | |
5bdc9b44 HC |
29 | } |
30 | ||
d0208639 | 31 | static int save_address(void *data, unsigned long address, int reliable) |
5bdc9b44 | 32 | { |
758d39eb HC |
33 | return __save_address(data, address, 0); |
34 | } | |
5bdc9b44 | 35 | |
d0208639 | 36 | static int save_address_nosched(void *data, unsigned long address, int reliable) |
758d39eb HC |
37 | { |
38 | return __save_address(data, address, 1); | |
66adce8f HC |
39 | } |
40 | ||
41 | void save_stack_trace(struct stack_trace *trace) | |
42 | { | |
66adce8f HC |
43 | unsigned long sp; |
44 | ||
76737ce1 | 45 | sp = current_stack_pointer(); |
758d39eb | 46 | dump_trace(save_address, trace, NULL, sp); |
f6331aac HC |
47 | if (trace->nr_entries < trace->max_entries) |
48 | trace->entries[trace->nr_entries++] = ULONG_MAX; | |
a3afe70b | 49 | } |
7b4c9505 | 50 | EXPORT_SYMBOL_GPL(save_stack_trace); |
a3afe70b HC |
51 | |
52 | void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) | |
53 | { | |
758d39eb | 54 | unsigned long sp; |
a3afe70b | 55 | |
9cb1ccec | 56 | sp = tsk->thread.ksp; |
76737ce1 HC |
57 | if (tsk == current) |
58 | sp = current_stack_pointer(); | |
758d39eb | 59 | dump_trace(save_address_nosched, trace, tsk, sp); |
a3afe70b HC |
60 | if (trace->nr_entries < trace->max_entries) |
61 | trace->entries[trace->nr_entries++] = ULONG_MAX; | |
5bdc9b44 | 62 | } |
7b4c9505 | 63 | EXPORT_SYMBOL_GPL(save_stack_trace_tsk); |
e0115875 PA |
64 | |
65 | void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) | |
66 | { | |
67 | unsigned long sp; | |
68 | ||
69 | sp = kernel_stack_pointer(regs); | |
758d39eb | 70 | dump_trace(save_address, trace, NULL, sp); |
e0115875 PA |
71 | if (trace->nr_entries < trace->max_entries) |
72 | trace->entries[trace->nr_entries++] = ULONG_MAX; | |
73 | } | |
74 | EXPORT_SYMBOL_GPL(save_stack_trace_regs); |