| 
									
										
										
										
											2009-06-26 16:28:00 +02:00
										 |  |  | #ifndef __PERF_CALLCHAIN_H
 | 
					
						
							|  |  |  | #define __PERF_CALLCHAIN_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "../perf.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-01 14:46:08 -03:00
										 |  |  | #include <linux/list.h>
 | 
					
						
							| 
									
										
										
										
											2009-07-01 12:28:37 -03:00
										 |  |  | #include <linux/rbtree.h>
 | 
					
						
							| 
									
										
										
										
											2010-05-09 11:47:13 -03:00
										 |  |  | #include "event.h"
 | 
					
						
							| 
									
										
										
										
											2009-07-01 05:35:14 +02:00
										 |  |  | #include "symbol.h"
 | 
					
						
							| 
									
										
										
										
											2009-06-26 16:28:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-02 17:58:21 +02:00
										 |  |  | enum chain_mode { | 
					
						
							| 
									
										
										
										
											2009-08-08 02:16:24 +02:00
										 |  |  | 	CHAIN_NONE, | 
					
						
							| 
									
										
										
										
											2009-07-05 07:39:21 +02:00
										 |  |  | 	CHAIN_FLAT, | 
					
						
							|  |  |  | 	CHAIN_GRAPH_ABS, | 
					
						
							|  |  |  | 	CHAIN_GRAPH_REL | 
					
						
							| 
									
										
										
										
											2009-07-02 17:58:21 +02:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2009-06-26 16:28:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-07 23:49:46 +08:00
										 |  |  | enum chain_order { | 
					
						
							|  |  |  | 	ORDER_CALLER, | 
					
						
							|  |  |  | 	ORDER_CALLEE | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-26 16:28:00 +02:00
										 |  |  | struct callchain_node { | 
					
						
							|  |  |  | 	struct callchain_node	*parent; | 
					
						
							| 
									
										
										
										
											2011-01-14 04:52:01 +01:00
										 |  |  | 	struct list_head	siblings; | 
					
						
							| 
									
										
										
										
											2009-07-01 12:37:06 +02:00
										 |  |  | 	struct list_head	children; | 
					
						
							|  |  |  | 	struct list_head	val; | 
					
						
							| 
									
										
										
										
											2009-07-02 17:58:21 +02:00
										 |  |  | 	struct rb_node		rb_node; /* to sort nodes in an rbtree */ | 
					
						
							|  |  |  | 	struct rb_root		rb_root; /* sorted tree of children */ | 
					
						
							| 
									
										
										
										
											2009-07-01 12:37:06 +02:00
										 |  |  | 	unsigned int		val_nr; | 
					
						
							|  |  |  | 	u64			hit; | 
					
						
							| 
									
										
										
										
											2009-08-07 07:11:05 +02:00
										 |  |  | 	u64			children_hit; | 
					
						
							| 
									
										
										
										
											2009-06-26 16:28:00 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-22 20:05:22 +02:00
										 |  |  | struct callchain_root { | 
					
						
							|  |  |  | 	u64			max_depth; | 
					
						
							|  |  |  | 	struct callchain_node	node; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-05 07:39:21 +02:00
										 |  |  | struct callchain_param; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-22 20:05:22 +02:00
										 |  |  | typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_root *, | 
					
						
							| 
									
										
										
										
											2009-07-05 07:39:21 +02:00
										 |  |  | 				 u64, struct callchain_param *); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct callchain_param { | 
					
						
							|  |  |  | 	enum chain_mode 	mode; | 
					
						
							| 
									
										
										
										
											2010-05-09 20:28:10 -03:00
										 |  |  | 	u32			print_limit; | 
					
						
							| 
									
										
										
										
											2009-07-05 07:39:21 +02:00
										 |  |  | 	double			min_percent; | 
					
						
							|  |  |  | 	sort_chain_func_t	sort; | 
					
						
							| 
									
										
										
										
											2011-06-07 23:49:46 +08:00
										 |  |  | 	enum chain_order	order; | 
					
						
							| 
									
										
										
										
											2009-07-05 07:39:21 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-26 16:28:00 +02:00
										 |  |  | struct callchain_list { | 
					
						
							| 
									
										
										
										
											2009-07-01 12:37:06 +02:00
										 |  |  | 	u64			ip; | 
					
						
							| 
									
										
										
										
											2010-03-24 16:40:18 -03:00
										 |  |  | 	struct map_symbol	ms; | 
					
						
							| 
									
										
										
										
											2009-06-26 16:28:00 +02:00
										 |  |  | 	struct list_head	list; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-14 04:51:58 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * A callchain cursor is a single linked list that | 
					
						
							|  |  |  |  * let one feed a callchain progressively. | 
					
						
							| 
									
										
										
										
											2012-07-18 01:20:59 +09:00
										 |  |  |  * It keeps persistent allocated entries to minimize | 
					
						
							| 
									
										
										
										
											2011-01-14 04:51:58 +01:00
										 |  |  |  * allocations. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | struct callchain_cursor_node { | 
					
						
							|  |  |  | 	u64				ip; | 
					
						
							|  |  |  | 	struct map			*map; | 
					
						
							|  |  |  | 	struct symbol			*sym; | 
					
						
							|  |  |  | 	struct callchain_cursor_node	*next; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct callchain_cursor { | 
					
						
							|  |  |  | 	u64				nr; | 
					
						
							|  |  |  | 	struct callchain_cursor_node	*first; | 
					
						
							|  |  |  | 	struct callchain_cursor_node	**last; | 
					
						
							|  |  |  | 	u64				pos; | 
					
						
							|  |  |  | 	struct callchain_cursor_node	*curr; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-31 14:43:26 +09:00
										 |  |  | extern __thread struct callchain_cursor callchain_cursor; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-22 20:05:22 +02:00
										 |  |  | static inline void callchain_init(struct callchain_root *root) | 
					
						
							| 
									
										
										
										
											2009-06-26 16:28:00 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-01-14 04:52:01 +01:00
										 |  |  | 	INIT_LIST_HEAD(&root->node.siblings); | 
					
						
							| 
									
										
										
										
											2010-08-22 20:05:22 +02:00
										 |  |  | 	INIT_LIST_HEAD(&root->node.children); | 
					
						
							|  |  |  | 	INIT_LIST_HEAD(&root->node.val); | 
					
						
							| 
									
										
										
										
											2010-07-08 06:06:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-22 20:05:22 +02:00
										 |  |  | 	root->node.parent = NULL; | 
					
						
							|  |  |  | 	root->node.hit = 0; | 
					
						
							| 
									
										
										
										
											2010-08-27 02:28:40 +02:00
										 |  |  | 	root->node.children_hit = 0; | 
					
						
							| 
									
										
										
										
											2010-08-22 20:05:22 +02:00
										 |  |  | 	root->max_depth = 0; | 
					
						
							| 
									
										
										
										
											2009-06-26 16:28:00 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-14 04:51:59 +01:00
										 |  |  | static inline u64 callchain_cumul_hits(struct callchain_node *node) | 
					
						
							| 
									
										
										
										
											2009-08-07 07:11:05 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	return node->hit + node->children_hit; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-14 04:52:00 +01:00
										 |  |  | int callchain_register_param(struct callchain_param *param); | 
					
						
							| 
									
										
										
										
											2011-01-14 04:51:58 +01:00
										 |  |  | int callchain_append(struct callchain_root *root, | 
					
						
							|  |  |  | 		     struct callchain_cursor *cursor, | 
					
						
							|  |  |  | 		     u64 period); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int callchain_merge(struct callchain_cursor *cursor, | 
					
						
							|  |  |  | 		    struct callchain_root *dst, struct callchain_root *src); | 
					
						
							| 
									
										
										
										
											2010-05-09 11:47:13 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-25 08:19:45 -02:00
										 |  |  | struct ip_callchain; | 
					
						
							|  |  |  | union perf_event; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-29 14:01:45 -02:00
										 |  |  | bool ip_callchain__valid(struct ip_callchain *chain, | 
					
						
							|  |  |  | 			 const union perf_event *event); | 
					
						
							| 
									
										
										
										
											2011-01-14 04:51:58 +01:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Initialize a cursor before adding entries inside, but keep | 
					
						
							|  |  |  |  * the previously allocated entries as a cache. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline void callchain_cursor_reset(struct callchain_cursor *cursor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	cursor->nr = 0; | 
					
						
							|  |  |  | 	cursor->last = &cursor->first; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int callchain_cursor_append(struct callchain_cursor *cursor, u64 ip, | 
					
						
							|  |  |  | 			    struct map *map, struct symbol *sym); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Close a cursor writing session. Initialize for the reader */ | 
					
						
							|  |  |  | static inline void callchain_cursor_commit(struct callchain_cursor *cursor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	cursor->curr = cursor->first; | 
					
						
							|  |  |  | 	cursor->pos = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Cursor reading iteration helpers */ | 
					
						
							|  |  |  | static inline struct callchain_cursor_node * | 
					
						
							|  |  |  | callchain_cursor_current(struct callchain_cursor *cursor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (cursor->pos == cursor->nr) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return cursor->curr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void callchain_cursor_advance(struct callchain_cursor *cursor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	cursor->curr = cursor->curr->next; | 
					
						
							|  |  |  | 	cursor->pos++; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2009-09-24 18:02:18 +02:00
										 |  |  | #endif	/* __PERF_CALLCHAIN_H */
 |