Skip to content

Commit 72ac426

Browse files
committed
tracing: Clean up stack tracing and fix fentry updates
Akashi Takahiro was porting the stack tracer to arm64 and found some issues with it. One was that it repeats the top function, due to the stack frame added by the mcount caller and added by itself. This was added when fentry came in, and before fentry created its own stack frame. But x86's fentry now creates its own stack frame, and there's no need to insert the function again. This also cleans up the code a bit, where it doesn't need to do something special for fentry, and doesn't include insertion of a duplicate entry for the called function being traced. Link: http://lkml.kernel.org/r/[email protected] Some-suggestions-by: Jungseok Lee <[email protected]> Some-suggestions-by: Mark Rutland <[email protected]> Reported-by: AKASHI Takahiro <[email protected]> Signed-off-by: Steven Rostedt <[email protected]>
1 parent d90fd77 commit 72ac426

File tree

1 file changed

+23
-45
lines changed

1 file changed

+23
-45
lines changed

kernel/trace/trace_stack.c

Lines changed: 23 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@
1818

1919
#define STACK_TRACE_ENTRIES 500
2020

21-
#ifdef CC_USING_FENTRY
22-
# define fentry 1
23-
#else
24-
# define fentry 0
25-
#endif
26-
2721
static unsigned long stack_dump_trace[STACK_TRACE_ENTRIES+1] =
2822
{ [0 ... (STACK_TRACE_ENTRIES)] = ULONG_MAX };
2923
static unsigned stack_dump_index[STACK_TRACE_ENTRIES];
@@ -35,7 +29,7 @@ static unsigned stack_dump_index[STACK_TRACE_ENTRIES];
3529
*/
3630
static struct stack_trace max_stack_trace = {
3731
.max_entries = STACK_TRACE_ENTRIES - 1,
38-
.entries = &stack_dump_trace[1],
32+
.entries = &stack_dump_trace[0],
3933
};
4034

4135
static unsigned long max_stack_size;
@@ -55,7 +49,7 @@ static inline void print_max_stack(void)
5549

5650
pr_emerg(" Depth Size Location (%d entries)\n"
5751
" ----- ---- --------\n",
58-
max_stack_trace.nr_entries - 1);
52+
max_stack_trace.nr_entries);
5953

6054
for (i = 0; i < max_stack_trace.nr_entries; i++) {
6155
if (stack_dump_trace[i] == ULONG_MAX)
@@ -77,7 +71,7 @@ check_stack(unsigned long ip, unsigned long *stack)
7771
unsigned long this_size, flags; unsigned long *p, *top, *start;
7872
static int tracer_frame;
7973
int frame_size = ACCESS_ONCE(tracer_frame);
80-
int i;
74+
int i, x;
8175

8276
this_size = ((unsigned long)stack) & (THREAD_SIZE-1);
8377
this_size = THREAD_SIZE - this_size;
@@ -105,26 +99,20 @@ check_stack(unsigned long ip, unsigned long *stack)
10599
max_stack_size = this_size;
106100

107101
max_stack_trace.nr_entries = 0;
108-
109-
if (using_ftrace_ops_list_func())
110-
max_stack_trace.skip = 4;
111-
else
112-
max_stack_trace.skip = 3;
102+
max_stack_trace.skip = 3;
113103

114104
save_stack_trace(&max_stack_trace);
115105

116-
/*
117-
* Add the passed in ip from the function tracer.
118-
* Searching for this on the stack will skip over
119-
* most of the overhead from the stack tracer itself.
120-
*/
121-
stack_dump_trace[0] = ip;
122-
max_stack_trace.nr_entries++;
106+
/* Skip over the overhead of the stack tracer itself */
107+
for (i = 0; i < max_stack_trace.nr_entries; i++) {
108+
if (stack_dump_trace[i] == ip)
109+
break;
110+
}
123111

124112
/*
125113
* Now find where in the stack these are.
126114
*/
127-
i = 0;
115+
x = 0;
128116
start = stack;
129117
top = (unsigned long *)
130118
(((unsigned long)start & ~(THREAD_SIZE-1)) + THREAD_SIZE);
@@ -139,12 +127,15 @@ check_stack(unsigned long ip, unsigned long *stack)
139127
while (i < max_stack_trace.nr_entries) {
140128
int found = 0;
141129

142-
stack_dump_index[i] = this_size;
130+
stack_dump_index[x] = this_size;
143131
p = start;
144132

145133
for (; p < top && i < max_stack_trace.nr_entries; p++) {
134+
if (stack_dump_trace[i] == ULONG_MAX)
135+
break;
146136
if (*p == stack_dump_trace[i]) {
147-
this_size = stack_dump_index[i++] =
137+
stack_dump_trace[x] = stack_dump_trace[i++];
138+
this_size = stack_dump_index[x++] =
148139
(top - p) * sizeof(unsigned long);
149140
found = 1;
150141
/* Start the search from here */
@@ -156,7 +147,7 @@ check_stack(unsigned long ip, unsigned long *stack)
156147
* out what that is, then figure it out
157148
* now.
158149
*/
159-
if (unlikely(!tracer_frame) && i == 1) {
150+
if (unlikely(!tracer_frame)) {
160151
tracer_frame = (p - stack) *
161152
sizeof(unsigned long);
162153
max_stack_size -= tracer_frame;
@@ -168,6 +159,10 @@ check_stack(unsigned long ip, unsigned long *stack)
168159
i++;
169160
}
170161

162+
max_stack_trace.nr_entries = x;
163+
for (; x < i; x++)
164+
stack_dump_trace[x] = ULONG_MAX;
165+
171166
if (task_stack_end_corrupted(current)) {
172167
print_max_stack();
173168
BUG();
@@ -192,24 +187,7 @@ stack_trace_call(unsigned long ip, unsigned long parent_ip,
192187
if (per_cpu(trace_active, cpu)++ != 0)
193188
goto out;
194189

195-
/*
196-
* When fentry is used, the traced function does not get
197-
* its stack frame set up, and we lose the parent.
198-
* The ip is pretty useless because the function tracer
199-
* was called before that function set up its stack frame.
200-
* In this case, we use the parent ip.
201-
*
202-
* By adding the return address of either the parent ip
203-
* or the current ip we can disregard most of the stack usage
204-
* caused by the stack tracer itself.
205-
*
206-
* The function tracer always reports the address of where the
207-
* mcount call was, but the stack will hold the return address.
208-
*/
209-
if (fentry)
210-
ip = parent_ip;
211-
else
212-
ip += MCOUNT_INSN_SIZE;
190+
ip += MCOUNT_INSN_SIZE;
213191

214192
check_stack(ip, &stack);
215193

@@ -284,7 +262,7 @@ __next(struct seq_file *m, loff_t *pos)
284262
{
285263
long n = *pos - 1;
286264

287-
if (n >= max_stack_trace.nr_entries || stack_dump_trace[n] == ULONG_MAX)
265+
if (n > max_stack_trace.nr_entries || stack_dump_trace[n] == ULONG_MAX)
288266
return NULL;
289267

290268
m->private = (void *)n;
@@ -354,7 +332,7 @@ static int t_show(struct seq_file *m, void *v)
354332
seq_printf(m, " Depth Size Location"
355333
" (%d entries)\n"
356334
" ----- ---- --------\n",
357-
max_stack_trace.nr_entries - 1);
335+
max_stack_trace.nr_entries);
358336

359337
if (!stack_tracer_enabled && !max_stack_size)
360338
print_disabled(m);

0 commit comments

Comments
 (0)