Skip to content

Commit ae51ce9

Browse files
author
Ingo Molnar
committed
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing into perf/core
2 parents 072b198 + 423478c commit ae51ce9

File tree

18 files changed

+121
-71
lines changed

18 files changed

+121
-71
lines changed

arch/x86/include/asm/kdebug.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ extern void die(const char *, struct pt_regs *,long);
2828
extern int __must_check __die(const char *, struct pt_regs *, long);
2929
extern void show_registers(struct pt_regs *regs);
3030
extern void show_trace(struct task_struct *t, struct pt_regs *regs,
31-
unsigned long *sp, unsigned long bp);
31+
unsigned long *sp);
3232
extern void __show_regs(struct pt_regs *regs, int all);
3333
extern void show_regs(struct pt_regs *regs);
3434
extern unsigned long oops_begin(void);

arch/x86/include/asm/stacktrace.h

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#define _ASM_X86_STACKTRACE_H
88

99
#include <linux/uaccess.h>
10+
#include <linux/ptrace.h>
1011

1112
extern int kstack_depth_to_print;
1213

@@ -46,7 +47,7 @@ struct stacktrace_ops {
4647
};
4748

4849
void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
49-
unsigned long *stack, unsigned long bp,
50+
unsigned long *stack,
5051
const struct stacktrace_ops *ops, void *data);
5152

5253
#ifdef CONFIG_X86_32
@@ -57,13 +58,39 @@ void dump_trace(struct task_struct *tsk, struct pt_regs *regs,
5758
#define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :)
5859
#endif
5960

61+
#ifdef CONFIG_FRAME_POINTER
62+
static inline unsigned long
63+
stack_frame(struct task_struct *task, struct pt_regs *regs)
64+
{
65+
unsigned long bp;
66+
67+
if (regs)
68+
return regs->bp;
69+
70+
if (task == current) {
71+
/* Grab bp right from our regs */
72+
get_bp(bp);
73+
return bp;
74+
}
75+
76+
/* bp is the last reg pushed by switch_to */
77+
return *(unsigned long *)task->thread.sp;
78+
}
79+
#else
80+
static inline unsigned long
81+
stack_frame(struct task_struct *task, struct pt_regs *regs)
82+
{
83+
return 0;
84+
}
85+
#endif
86+
6087
extern void
6188
show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
62-
unsigned long *stack, unsigned long bp, char *log_lvl);
89+
unsigned long *stack, char *log_lvl);
6390

6491
extern void
6592
show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
66-
unsigned long *sp, unsigned long bp, char *log_lvl);
93+
unsigned long *sp, char *log_lvl);
6794

6895
extern unsigned int code_bytes;
6996

arch/x86/kernel/cpu/perf_event.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1657,7 +1657,7 @@ perf_callchain_kernel(struct perf_callchain_entry *entry, struct pt_regs *regs)
16571657

16581658
perf_callchain_store(entry, regs->ip);
16591659

1660-
dump_trace(NULL, regs, NULL, regs->bp, &backtrace_ops, entry);
1660+
dump_trace(NULL, regs, NULL, &backtrace_ops, entry);
16611661
}
16621662

16631663
#ifdef CONFIG_COMPAT

arch/x86/kernel/dumpstack.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -175,21 +175,21 @@ static const struct stacktrace_ops print_trace_ops = {
175175

176176
void
177177
show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs,
178-
unsigned long *stack, unsigned long bp, char *log_lvl)
178+
unsigned long *stack, char *log_lvl)
179179
{
180180
printk("%sCall Trace:\n", log_lvl);
181-
dump_trace(task, regs, stack, bp, &print_trace_ops, log_lvl);
181+
dump_trace(task, regs, stack, &print_trace_ops, log_lvl);
182182
}
183183

184184
void show_trace(struct task_struct *task, struct pt_regs *regs,
185-
unsigned long *stack, unsigned long bp)
185+
unsigned long *stack)
186186
{
187-
show_trace_log_lvl(task, regs, stack, bp, "");
187+
show_trace_log_lvl(task, regs, stack, "");
188188
}
189189

190190
void show_stack(struct task_struct *task, unsigned long *sp)
191191
{
192-
show_stack_log_lvl(task, NULL, sp, 0, "");
192+
show_stack_log_lvl(task, NULL, sp, "");
193193
}
194194

195195
/*
@@ -210,7 +210,7 @@ void dump_stack(void)
210210
init_utsname()->release,
211211
(int)strcspn(init_utsname()->version, " "),
212212
init_utsname()->version);
213-
show_trace(NULL, NULL, &stack, bp);
213+
show_trace(NULL, NULL, &stack);
214214
}
215215
EXPORT_SYMBOL(dump_stack);
216216

arch/x86/kernel/dumpstack_32.c

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
#include <asm/stacktrace.h>
1818

1919

20-
void dump_trace(struct task_struct *task, struct pt_regs *regs,
21-
unsigned long *stack, unsigned long bp,
20+
void dump_trace(struct task_struct *task,
21+
struct pt_regs *regs, unsigned long *stack,
2222
const struct stacktrace_ops *ops, void *data)
2323
{
2424
int graph = 0;
25+
unsigned long bp;
2526

2627
if (!task)
2728
task = current;
@@ -34,18 +35,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
3435
stack = (unsigned long *)task->thread.sp;
3536
}
3637

37-
#ifdef CONFIG_FRAME_POINTER
38-
if (!bp) {
39-
if (task == current) {
40-
/* Grab bp right from our regs */
41-
get_bp(bp);
42-
} else {
43-
/* bp is the last reg pushed by switch_to */
44-
bp = *(unsigned long *) task->thread.sp;
45-
}
46-
}
47-
#endif
48-
38+
bp = stack_frame(task, regs);
4939
for (;;) {
5040
struct thread_info *context;
5141

@@ -65,7 +55,7 @@ EXPORT_SYMBOL(dump_trace);
6555

6656
void
6757
show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
68-
unsigned long *sp, unsigned long bp, char *log_lvl)
58+
unsigned long *sp, char *log_lvl)
6959
{
7060
unsigned long *stack;
7161
int i;
@@ -87,7 +77,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
8777
touch_nmi_watchdog();
8878
}
8979
printk(KERN_CONT "\n");
90-
show_trace_log_lvl(task, regs, sp, bp, log_lvl);
80+
show_trace_log_lvl(task, regs, sp, log_lvl);
9181
}
9282

9383

@@ -112,8 +102,7 @@ void show_registers(struct pt_regs *regs)
112102
u8 *ip;
113103

114104
printk(KERN_EMERG "Stack:\n");
115-
show_stack_log_lvl(NULL, regs, &regs->sp,
116-
0, KERN_EMERG);
105+
show_stack_log_lvl(NULL, regs, &regs->sp, KERN_EMERG);
117106

118107
printk(KERN_EMERG "Code: ");
119108

arch/x86/kernel/dumpstack_64.c

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ fixup_bp_irq_link(unsigned long bp, unsigned long *stack,
139139
* severe exception (double fault, nmi, stack fault, debug, mce) hardware stack
140140
*/
141141

142-
void dump_trace(struct task_struct *task, struct pt_regs *regs,
143-
unsigned long *stack, unsigned long bp,
142+
void dump_trace(struct task_struct *task,
143+
struct pt_regs *regs, unsigned long *stack,
144144
const struct stacktrace_ops *ops, void *data)
145145
{
146146
const unsigned cpu = get_cpu();
@@ -149,6 +149,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
149149
unsigned used = 0;
150150
struct thread_info *tinfo;
151151
int graph = 0;
152+
unsigned long bp;
152153

153154
if (!task)
154155
task = current;
@@ -160,18 +161,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
160161
stack = (unsigned long *)task->thread.sp;
161162
}
162163

163-
#ifdef CONFIG_FRAME_POINTER
164-
if (!bp) {
165-
if (task == current) {
166-
/* Grab bp right from our regs */
167-
get_bp(bp);
168-
} else {
169-
/* bp is the last reg pushed by switch_to */
170-
bp = *(unsigned long *) task->thread.sp;
171-
}
172-
}
173-
#endif
174-
164+
bp = stack_frame(task, regs);
175165
/*
176166
* Print function call entries in all stacks, starting at the
177167
* current stack address. If the stacks consist of nested
@@ -235,7 +225,7 @@ EXPORT_SYMBOL(dump_trace);
235225

236226
void
237227
show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
238-
unsigned long *sp, unsigned long bp, char *log_lvl)
228+
unsigned long *sp, char *log_lvl)
239229
{
240230
unsigned long *irq_stack_end;
241231
unsigned long *irq_stack;
@@ -279,7 +269,7 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
279269
preempt_enable();
280270

281271
printk(KERN_CONT "\n");
282-
show_trace_log_lvl(task, regs, sp, bp, log_lvl);
272+
show_trace_log_lvl(task, regs, sp, log_lvl);
283273
}
284274

285275
void show_registers(struct pt_regs *regs)
@@ -308,7 +298,7 @@ void show_registers(struct pt_regs *regs)
308298

309299
printk(KERN_EMERG "Stack:\n");
310300
show_stack_log_lvl(NULL, regs, (unsigned long *)sp,
311-
regs->bp, KERN_EMERG);
301+
KERN_EMERG);
312302

313303
printk(KERN_EMERG "Code: ");
314304

arch/x86/kernel/process.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ void exit_thread(void)
9191
void show_regs(struct pt_regs *regs)
9292
{
9393
show_registers(regs);
94-
show_trace(NULL, regs, (unsigned long *)kernel_stack_pointer(regs),
95-
regs->bp);
94+
show_trace(NULL, regs, (unsigned long *)kernel_stack_pointer(regs));
9695
}
9796

9897
void show_regs_common(void)

arch/x86/kernel/stacktrace.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,22 +73,22 @@ static const struct stacktrace_ops save_stack_ops_nosched = {
7373
*/
7474
void save_stack_trace(struct stack_trace *trace)
7575
{
76-
dump_trace(current, NULL, NULL, 0, &save_stack_ops, trace);
76+
dump_trace(current, NULL, NULL, &save_stack_ops, trace);
7777
if (trace->nr_entries < trace->max_entries)
7878
trace->entries[trace->nr_entries++] = ULONG_MAX;
7979
}
8080
EXPORT_SYMBOL_GPL(save_stack_trace);
8181

82-
void save_stack_trace_bp(struct stack_trace *trace, unsigned long bp)
82+
void save_stack_trace_regs(struct stack_trace *trace, struct pt_regs *regs)
8383
{
84-
dump_trace(current, NULL, NULL, bp, &save_stack_ops, trace);
84+
dump_trace(current, regs, NULL, &save_stack_ops, trace);
8585
if (trace->nr_entries < trace->max_entries)
8686
trace->entries[trace->nr_entries++] = ULONG_MAX;
8787
}
8888

8989
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
9090
{
91-
dump_trace(tsk, NULL, NULL, 0, &save_stack_ops_nosched, trace);
91+
dump_trace(tsk, NULL, NULL, &save_stack_ops_nosched, trace);
9292
if (trace->nr_entries < trace->max_entries)
9393
trace->entries[trace->nr_entries++] = ULONG_MAX;
9494
}

arch/x86/mm/kmemcheck/error.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ void kmemcheck_error_save(enum kmemcheck_shadow state,
185185
e->trace.entries = e->trace_entries;
186186
e->trace.max_entries = ARRAY_SIZE(e->trace_entries);
187187
e->trace.skip = 0;
188-
save_stack_trace_bp(&e->trace, regs->bp);
188+
save_stack_trace_regs(&e->trace, regs);
189189

190190
/* Round address down to nearest 16 bytes */
191191
shadow_copy = kmemcheck_shadow_lookup(address

arch/x86/oprofile/backtrace.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ x86_backtrace(struct pt_regs * const regs, unsigned int depth)
126126
if (!user_mode_vm(regs)) {
127127
unsigned long stack = kernel_stack_pointer(regs);
128128
if (depth)
129-
dump_trace(NULL, regs, (unsigned long *)stack, 0,
129+
dump_trace(NULL, regs, (unsigned long *)stack,
130130
&backtrace_ops, &depth);
131131
return;
132132
}

0 commit comments

Comments
 (0)