diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sparc/include/asm/cache.h | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/perf_event.c | 14 | ||||
-rw-r--r-- | arch/sparc/kernel/process_64.c | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/stacktrace.c | 23 | ||||
-rw-r--r-- | arch/sparc/kernel/traps_64.c | 14 |
5 files changed, 53 insertions, 1 deletions
diff --git a/arch/sparc/include/asm/cache.h b/arch/sparc/include/asm/cache.h index 41f85ae4bd4a..78b07009f60a 100644 --- a/arch/sparc/include/asm/cache.h +++ b/arch/sparc/include/asm/cache.h | |||
@@ -7,6 +7,8 @@ | |||
7 | #ifndef _SPARC_CACHE_H | 7 | #ifndef _SPARC_CACHE_H |
8 | #define _SPARC_CACHE_H | 8 | #define _SPARC_CACHE_H |
9 | 9 | ||
10 | #define ARCH_SLAB_MINALIGN __alignof__(unsigned long long) | ||
11 | |||
10 | #define L1_CACHE_SHIFT 5 | 12 | #define L1_CACHE_SHIFT 5 |
11 | #define L1_CACHE_BYTES 32 | 13 | #define L1_CACHE_BYTES 32 |
12 | #define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))) | 14 | #define L1_CACHE_ALIGN(x) ((((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1))) |
diff --git a/arch/sparc/kernel/perf_event.c b/arch/sparc/kernel/perf_event.c index e2771939341d..34ce49f80eac 100644 --- a/arch/sparc/kernel/perf_event.c +++ b/arch/sparc/kernel/perf_event.c | |||
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include <linux/perf_event.h> | 15 | #include <linux/perf_event.h> |
16 | #include <linux/kprobes.h> | 16 | #include <linux/kprobes.h> |
17 | #include <linux/ftrace.h> | ||
17 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
18 | #include <linux/kdebug.h> | 19 | #include <linux/kdebug.h> |
19 | #include <linux/mutex.h> | 20 | #include <linux/mutex.h> |
@@ -1276,6 +1277,9 @@ static void perf_callchain_kernel(struct pt_regs *regs, | |||
1276 | struct perf_callchain_entry *entry) | 1277 | struct perf_callchain_entry *entry) |
1277 | { | 1278 | { |
1278 | unsigned long ksp, fp; | 1279 | unsigned long ksp, fp; |
1280 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
1281 | int graph = 0; | ||
1282 | #endif | ||
1279 | 1283 | ||
1280 | callchain_store(entry, PERF_CONTEXT_KERNEL); | 1284 | callchain_store(entry, PERF_CONTEXT_KERNEL); |
1281 | callchain_store(entry, regs->tpc); | 1285 | callchain_store(entry, regs->tpc); |
@@ -1303,6 +1307,16 @@ static void perf_callchain_kernel(struct pt_regs *regs, | |||
1303 | fp = (unsigned long)sf->fp + STACK_BIAS; | 1307 | fp = (unsigned long)sf->fp + STACK_BIAS; |
1304 | } | 1308 | } |
1305 | callchain_store(entry, pc); | 1309 | callchain_store(entry, pc); |
1310 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
1311 | if ((pc + 8UL) == (unsigned long) &return_to_handler) { | ||
1312 | int index = current->curr_ret_stack; | ||
1313 | if (current->ret_stack && index >= graph) { | ||
1314 | pc = current->ret_stack[index - graph].ret; | ||
1315 | callchain_store(entry, pc); | ||
1316 | graph++; | ||
1317 | } | ||
1318 | } | ||
1319 | #endif | ||
1306 | } while (entry->nr < PERF_MAX_STACK_DEPTH); | 1320 | } while (entry->nr < PERF_MAX_STACK_DEPTH); |
1307 | } | 1321 | } |
1308 | 1322 | ||
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c index a5cf3864b31f..dbe81a368b45 100644 --- a/arch/sparc/kernel/process_64.c +++ b/arch/sparc/kernel/process_64.c | |||
@@ -202,6 +202,7 @@ void show_regs(struct pt_regs *regs) | |||
202 | regs->u_regs[15]); | 202 | regs->u_regs[15]); |
203 | printk("RPC: <%pS>\n", (void *) regs->u_regs[15]); | 203 | printk("RPC: <%pS>\n", (void *) regs->u_regs[15]); |
204 | show_regwindow(regs); | 204 | show_regwindow(regs); |
205 | show_stack(current, (unsigned long *) regs->u_regs[UREG_FP]); | ||
205 | } | 206 | } |
206 | 207 | ||
207 | struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; | 208 | struct global_reg_snapshot global_reg_snapshot[NR_CPUS]; |
diff --git a/arch/sparc/kernel/stacktrace.c b/arch/sparc/kernel/stacktrace.c index acb12f673757..3e0815349630 100644 --- a/arch/sparc/kernel/stacktrace.c +++ b/arch/sparc/kernel/stacktrace.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <linux/sched.h> | 1 | #include <linux/sched.h> |
2 | #include <linux/stacktrace.h> | 2 | #include <linux/stacktrace.h> |
3 | #include <linux/thread_info.h> | 3 | #include <linux/thread_info.h> |
4 | #include <linux/ftrace.h> | ||
4 | #include <linux/module.h> | 5 | #include <linux/module.h> |
5 | #include <asm/ptrace.h> | 6 | #include <asm/ptrace.h> |
6 | #include <asm/stacktrace.h> | 7 | #include <asm/stacktrace.h> |
@@ -12,6 +13,10 @@ static void __save_stack_trace(struct thread_info *tp, | |||
12 | bool skip_sched) | 13 | bool skip_sched) |
13 | { | 14 | { |
14 | unsigned long ksp, fp; | 15 | unsigned long ksp, fp; |
16 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
17 | struct task_struct *t; | ||
18 | int graph = 0; | ||
19 | #endif | ||
15 | 20 | ||
16 | if (tp == current_thread_info()) { | 21 | if (tp == current_thread_info()) { |
17 | stack_trace_flush(); | 22 | stack_trace_flush(); |
@@ -21,6 +26,9 @@ static void __save_stack_trace(struct thread_info *tp, | |||
21 | } | 26 | } |
22 | 27 | ||
23 | fp = ksp + STACK_BIAS; | 28 | fp = ksp + STACK_BIAS; |
29 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
30 | t = tp->task; | ||
31 | #endif | ||
24 | do { | 32 | do { |
25 | struct sparc_stackf *sf; | 33 | struct sparc_stackf *sf; |
26 | struct pt_regs *regs; | 34 | struct pt_regs *regs; |
@@ -44,8 +52,21 @@ static void __save_stack_trace(struct thread_info *tp, | |||
44 | 52 | ||
45 | if (trace->skip > 0) | 53 | if (trace->skip > 0) |
46 | trace->skip--; | 54 | trace->skip--; |
47 | else if (!skip_sched || !in_sched_functions(pc)) | 55 | else if (!skip_sched || !in_sched_functions(pc)) { |
48 | trace->entries[trace->nr_entries++] = pc; | 56 | trace->entries[trace->nr_entries++] = pc; |
57 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
58 | if ((pc + 8UL) == (unsigned long) &return_to_handler) { | ||
59 | int index = t->curr_ret_stack; | ||
60 | if (t->ret_stack && index >= graph) { | ||
61 | pc = t->ret_stack[index - graph].ret; | ||
62 | if (trace->nr_entries < | ||
63 | trace->max_entries) | ||
64 | trace->entries[trace->nr_entries++] = pc; | ||
65 | graph++; | ||
66 | } | ||
67 | } | ||
68 | #endif | ||
69 | } | ||
49 | } while (trace->nr_entries < trace->max_entries); | 70 | } while (trace->nr_entries < trace->max_entries); |
50 | } | 71 | } |
51 | 72 | ||
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index 9da57f032983..42ad2ba85010 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/kdebug.h> | 19 | #include <linux/kdebug.h> |
20 | #include <linux/ftrace.h> | ||
20 | #include <linux/gfp.h> | 21 | #include <linux/gfp.h> |
21 | 22 | ||
22 | #include <asm/smp.h> | 23 | #include <asm/smp.h> |
@@ -2154,6 +2155,9 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) | |||
2154 | unsigned long fp, thread_base, ksp; | 2155 | unsigned long fp, thread_base, ksp; |
2155 | struct thread_info *tp; | 2156 | struct thread_info *tp; |
2156 | int count = 0; | 2157 | int count = 0; |
2158 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
2159 | int graph = 0; | ||
2160 | #endif | ||
2157 | 2161 | ||
2158 | ksp = (unsigned long) _ksp; | 2162 | ksp = (unsigned long) _ksp; |
2159 | if (!tsk) | 2163 | if (!tsk) |
@@ -2193,6 +2197,16 @@ void show_stack(struct task_struct *tsk, unsigned long *_ksp) | |||
2193 | } | 2197 | } |
2194 | 2198 | ||
2195 | printk(" [%016lx] %pS\n", pc, (void *) pc); | 2199 | printk(" [%016lx] %pS\n", pc, (void *) pc); |
2200 | #ifdef CONFIG_FUNCTION_GRAPH_TRACER | ||
2201 | if ((pc + 8UL) == (unsigned long) &return_to_handler) { | ||
2202 | int index = tsk->curr_ret_stack; | ||
2203 | if (tsk->ret_stack && index >= graph) { | ||
2204 | pc = tsk->ret_stack[index - graph].ret; | ||
2205 | printk(" [%016lx] %pS\n", pc, (void *) pc); | ||
2206 | graph++; | ||
2207 | } | ||
2208 | } | ||
2209 | #endif | ||
2196 | } while (++count < 16); | 2210 | } while (++count < 16); |
2197 | } | 2211 | } |
2198 | 2212 | ||