Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cf3271a7 authored by Soeren Sandmann's avatar Soeren Sandmann Committed by Thomas Gleixner
Browse files

ftrace/sysprof: don't trace the user stack if we are a kernel thread.



Check that current->mm is non-NULL before attempting to trace the user
stack.

Also take depth of the kernel stack into account when comparing
against sample_max_depth.

Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 8a9e94c1
Loading
Loading
Loading
Loading
+29 −21
Original line number Diff line number Diff line
@@ -95,13 +95,12 @@ const static struct stacktrace_ops backtrace_ops = {
	.address		= backtrace_address,
};

static struct pt_regs *
static int
trace_kernel(struct pt_regs *regs, struct trace_array *tr,
	     struct trace_array_cpu *data)
{
	struct backtrace_info info;
	unsigned long bp;
	char *user_stack;
	char *stack;

	info.tr = tr;
@@ -119,10 +118,7 @@ trace_kernel(struct pt_regs *regs, struct trace_array *tr,

	dump_trace(NULL, regs, (void *)stack, bp, &backtrace_ops, &info);

	/* Now trace the user stack */
	user_stack = ((char *)current->thread.sp0 - sizeof(struct pt_regs));

	return (struct pt_regs *)user_stack;
	return info.pos;
}

static void timer_notify(struct pt_regs *regs, int cpu)
@@ -150,13 +146,21 @@ static void timer_notify(struct pt_regs *regs, int cpu)
	__trace_special(tr, data, 0, 0, current->pid);

	if (!is_user)
		regs = trace_kernel(regs, tr, data);
		i = trace_kernel(regs, tr, data);
	else
		i = 0;

	/*
	 * Trace user stack if we are not a kernel thread
	 */
	if (current->mm && i < sample_max_depth) {
		regs = (struct pt_regs *)current->thread.sp0 - 1;

		fp = (void __user *)regs->bp;

		__trace_special(tr, data, 2, regs->ip, 0);

	for (i = 0; i < sample_max_depth; i++) {
		while (i < sample_max_depth) {
			frame.next_fp = 0;
			frame.return_address = 0;
			if (!copy_stack_frame(fp, &frame))
@@ -167,15 +171,19 @@ static void timer_notify(struct pt_regs *regs, int cpu)
			__trace_special(tr, data, 2, frame.return_address,
					(unsigned long)fp);
			fp = frame.next_fp;

			i++;
		}

	__trace_special(tr, data, 3, current->pid, i);
	}

	/*
	 * Special trace entry if we overflow the max depth:
	 */
	if (i == sample_max_depth)
		__trace_special(tr, data, -1, -1, -1);

	__trace_special(tr, data, 3, current->pid, i);
}

static enum hrtimer_restart stack_trace_timer_fn(struct hrtimer *hrtimer)