mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	 b3eac0265b
			
		
	
	
		b3eac0265b
		
	
	
	
	
		
			
			For ARM, when tracing with tracepoint events, the IP and cpsr are set
to 0, preventing the perf code parsing the callchain and resolving the
symbols correctly.
 ./perf record -e sched:sched_switch -g --call-graph dwarf ls
    [ perf record: Captured and wrote 0.006 MB perf.data ]
 ./perf report -f
    Samples: 5  of event 'sched:sched_switch', Event count (approx.): 5
    Children      Self    Command  Shared Object     Symbol
    100.00%       100.00%  ls       [unknown]         [.] 00000000
The fix is to implement perf_arch_fetch_caller_regs for ARM, which fills
several necessary registers used for callchain unwinding, including pc,sp,
fp and cpsr.
With this patch, callchain can be parsed correctly as :
   .....
-  100.00%   100.00%  ls       [kernel.kallsyms]  [k] __sched_text_start
   + __sched_text_start
+   20.00%     0.00%  ls       libc-2.18.so       [.] _dl_addr
+   20.00%     0.00%  ls       libc-2.18.so       [.] write
   .....
Jean Pihet found this in ARM and come up with a patch:
http://thread.gmane.org/gmane.linux.kernel/1734283/focus=1734280
This patch rewrite Jean's patch in C.
Signed-off-by: Hou Pengyang <houpengyang@huawei.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
		
	
			
		
			
				
	
	
		
			30 lines
		
	
	
		
			850 B
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			30 lines
		
	
	
		
			850 B
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  *  linux/arch/arm/include/asm/perf_event.h
 | |
|  *
 | |
|  *  Copyright (C) 2009 picoChip Designs Ltd, Jamie Iles
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU General Public License version 2 as
 | |
|  * published by the Free Software Foundation.
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #ifndef __ARM_PERF_EVENT_H__
 | |
| #define __ARM_PERF_EVENT_H__
 | |
| 
 | |
| #ifdef CONFIG_PERF_EVENTS
 | |
| struct pt_regs;
 | |
| extern unsigned long perf_instruction_pointer(struct pt_regs *regs);
 | |
| extern unsigned long perf_misc_flags(struct pt_regs *regs);
 | |
| #define perf_misc_flags(regs)	perf_misc_flags(regs)
 | |
| #endif
 | |
| 
 | |
| #define perf_arch_fetch_caller_regs(regs, __ip) { \
 | |
| 	(regs)->ARM_pc = (__ip); \
 | |
| 	(regs)->ARM_fp = (unsigned long) __builtin_frame_address(0); \
 | |
| 	(regs)->ARM_sp = current_stack_pointer; \
 | |
| 	(regs)->ARM_cpsr = SVC_MODE; \
 | |
| }
 | |
| 
 | |
| #endif /* __ARM_PERF_EVENT_H__ */
 |