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

Commit f76e9154 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Lennert Buytenhek
Browse files

[ARM] latencytop support



Available for !SMP only at the moment.

From Russell:

|Basically, if a thread is running on a CPU, thread_saved_fp() is invalid.
|So, the question is: what guarantees do we have here that 'tsk' is not
|running on another CPU?

Signed-off-by: default avatarNicolas Pitre <nico@marvell.com>
Tested-by: default avatarLennert Buytenhek <buytenh@marvell.com>
Signed-off-by: default avatarLennert Buytenhek <buytenh@marvell.com>
parent b0bfcce9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -84,6 +84,11 @@ config STACKTRACE_SUPPORT
	bool
	default y

config HAVE_LATENCYTOP_SUPPORT
	bool
	depends on !SMP
	default y

config LOCKDEP_SUPPORT
	bool
	default y
+30 −4
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ EXPORT_SYMBOL(walk_stackframe);
#ifdef CONFIG_STACKTRACE
struct stack_trace_data {
	struct stack_trace *trace;
	unsigned int no_sched_functions;
	unsigned int skip;
};

@@ -43,27 +44,52 @@ static int save_trace(struct stackframe *frame, void *d)
{
	struct stack_trace_data *data = d;
	struct stack_trace *trace = data->trace;
	unsigned long addr = frame->lr;

	if (data->no_sched_functions && in_sched_functions(addr))
		return 0;
	if (data->skip) {
		data->skip--;
		return 0;
	}

	trace->entries[trace->nr_entries++] = frame->lr;
	trace->entries[trace->nr_entries++] = addr;

	return trace->nr_entries >= trace->max_entries;
}

void save_stack_trace(struct stack_trace *trace)
void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
{
	struct stack_trace_data data;
	unsigned long fp, base;

	data.trace = trace;
	data.skip = trace->skip;
	base = (unsigned long)task_stack_page(current);
	base = (unsigned long)task_stack_page(tsk);

	if (tsk != current) {
#ifdef CONFIG_SMP
		/*
		 * What guarantees do we have here that 'tsk'
		 * is not running on another CPU?
		 */
		BUG();
#else
		data.no_sched_functions = 1;
		fp = thread_saved_fp(tsk);
#endif
	} else {
		data.no_sched_functions = 0;
		asm("mov %0, fp" : "=r" (fp));
	}

	walk_stackframe(fp, base, base + THREAD_SIZE, save_trace, &data);
	if (trace->nr_entries < trace->max_entries)
		trace->entries[trace->nr_entries++] = ULONG_MAX;
}

void save_stack_trace(struct stack_trace *trace)
{
	save_stack_trace_tsk(current, trace);
}
#endif