 ab1b6f03a1
			
		
	
	
	ab1b6f03a1
	
	
	
		
			
			Simplify the stacktrace code: - remove the unused task argument to save_stack_trace, it's always current - remove the all_contexts flag, it's alwasy 0 Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Paul Mundt <lethal@linux-sh.org> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: Andi Kleen <ak@suse.de> Cc: Akinobu Mita <akinobu.mita@gmail.com> Acked-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
		
			
				
	
	
		
			75 lines
		
	
	
	
		
			1.7 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			75 lines
		
	
	
	
		
			1.7 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * arch/mips/kernel/stacktrace.c
 | |
|  *
 | |
|  * Stack trace management functions
 | |
|  *
 | |
|  *  Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
 | |
|  */
 | |
| #include <linux/sched.h>
 | |
| #include <linux/stacktrace.h>
 | |
| #include <asm/stacktrace.h>
 | |
| 
 | |
| /*
 | |
|  * Save stack-backtrace addresses into a stack_trace buffer:
 | |
|  */
 | |
| static void save_raw_context_stack(struct stack_trace *trace,
 | |
| 	unsigned long reg29)
 | |
| {
 | |
| 	unsigned long *sp = (unsigned long *)reg29;
 | |
| 	unsigned long addr;
 | |
| 
 | |
| 	while (!kstack_end(sp)) {
 | |
| 		addr = *sp++;
 | |
| 		if (__kernel_text_address(addr)) {
 | |
| 			if (trace->skip > 0)
 | |
| 				trace->skip--;
 | |
| 			else
 | |
| 				trace->entries[trace->nr_entries++] = addr;
 | |
| 			if (trace->nr_entries >= trace->max_entries)
 | |
| 				break;
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| static void save_context_stack(struct stack_trace *trace, struct pt_regs *regs)
 | |
| {
 | |
| 	unsigned long sp = regs->regs[29];
 | |
| #ifdef CONFIG_KALLSYMS
 | |
| 	unsigned long ra = regs->regs[31];
 | |
| 	unsigned long pc = regs->cp0_epc;
 | |
| 
 | |
| 	if (raw_show_trace || !__kernel_text_address(pc)) {
 | |
| 		unsigned long stack_page =
 | |
| 			(unsigned long)task_stack_page(current);
 | |
| 		if (stack_page && sp >= stack_page &&
 | |
| 		    sp <= stack_page + THREAD_SIZE - 32)
 | |
| 			save_raw_context_stack(trace, sp);
 | |
| 		return;
 | |
| 	}
 | |
| 	do {
 | |
| 		if (trace->skip > 0)
 | |
| 			trace->skip--;
 | |
| 		else
 | |
| 			trace->entries[trace->nr_entries++] = pc;
 | |
| 		if (trace->nr_entries >= trace->max_entries)
 | |
| 			break;
 | |
| 		pc = unwind_stack(current, &sp, pc, &ra);
 | |
| 	} while (pc);
 | |
| #else
 | |
| 	save_raw_context_stack(trace, sp);
 | |
| #endif
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Save stack-backtrace addresses into a stack_trace buffer.
 | |
|  */
 | |
| void save_stack_trace(struct stack_trace *trace)
 | |
| {
 | |
| 	struct pt_regs dummyregs;
 | |
| 	struct pt_regs *regs = &dummyregs;
 | |
| 
 | |
| 	WARN_ON(trace->nr_entries || !trace->max_entries);
 | |
| 
 | |
| 	prepare_frametrace(regs);
 | |
| 	save_context_stack(trace, regs);
 | |
| }
 |