0001
0002 #ifndef __PERF_SORT_H
0003 #define __PERF_SORT_H
0004 #include <regex.h>
0005 #include <stdbool.h>
0006 #include <linux/list.h>
0007 #include <linux/rbtree.h>
0008 #include "map_symbol.h"
0009 #include "symbol_conf.h"
0010 #include "callchain.h"
0011 #include "values.h"
0012 #include "hist.h"
0013 #include "stat.h"
0014 #include "spark.h"
0015
0016 struct option;
0017 struct thread;
0018
0019 extern regex_t parent_regex;
0020 extern const char *sort_order;
0021 extern const char *field_order;
0022 extern const char default_parent_pattern[];
0023 extern const char *parent_pattern;
0024 extern const char *default_sort_order;
0025 extern regex_t ignore_callees_regex;
0026 extern int have_ignore_callees;
0027 extern enum sort_mode sort__mode;
0028 extern struct sort_entry sort_comm;
0029 extern struct sort_entry sort_dso;
0030 extern struct sort_entry sort_sym;
0031 extern struct sort_entry sort_parent;
0032 extern struct sort_entry sort_dso_from;
0033 extern struct sort_entry sort_dso_to;
0034 extern struct sort_entry sort_sym_from;
0035 extern struct sort_entry sort_sym_to;
0036 extern struct sort_entry sort_srcline;
0037 extern enum sort_type sort__first_dimension;
0038 extern const char default_mem_sort_order[];
0039
0040 struct res_sample {
0041 u64 time;
0042 int cpu;
0043 int tid;
0044 };
0045
0046 struct he_stat {
0047 u64 period;
0048 u64 period_sys;
0049 u64 period_us;
0050 u64 period_guest_sys;
0051 u64 period_guest_us;
0052 u32 nr_events;
0053 };
0054
0055 struct namespace_id {
0056 u64 dev;
0057 u64 ino;
0058 };
0059
0060 struct hist_entry_diff {
0061 bool computed;
0062 union {
0063
0064 double period_ratio_delta;
0065
0066
0067 double period_ratio;
0068
0069
0070 s64 wdiff;
0071
0072
0073 s64 cycles;
0074 };
0075 struct stats stats;
0076 unsigned long svals[NUM_SPARKS];
0077 };
0078
0079 struct hist_entry_ops {
0080 void *(*new)(size_t size);
0081 void (*free)(void *ptr);
0082 };
0083
0084
0085
0086
0087
0088
0089
0090 struct hist_entry {
0091 struct rb_node rb_node_in;
0092 struct rb_node rb_node;
0093 union {
0094 struct list_head node;
0095 struct list_head head;
0096 } pairs;
0097 struct he_stat stat;
0098 struct he_stat *stat_acc;
0099 struct map_symbol ms;
0100 struct thread *thread;
0101 struct comm *comm;
0102 struct namespace_id cgroup_id;
0103 u64 cgroup;
0104 u64 ip;
0105 u64 transaction;
0106 s32 socket;
0107 s32 cpu;
0108 u64 code_page_size;
0109 u64 weight;
0110 u64 ins_lat;
0111 u64 p_stage_cyc;
0112 u8 cpumode;
0113 u8 depth;
0114
0115
0116 bool dummy;
0117 bool leaf;
0118
0119 char level;
0120 u8 filtered;
0121
0122 u16 callchain_size;
0123 union {
0124
0125
0126
0127
0128
0129 struct hist_entry_diff diff;
0130 struct {
0131 u16 row_offset;
0132 u16 nr_rows;
0133 bool init_have_children;
0134 bool unfolded;
0135 bool has_children;
0136 bool has_no_entry;
0137 };
0138 };
0139 char *srcline;
0140 char *srcfile;
0141 struct symbol *parent;
0142 struct branch_info *branch_info;
0143 long time;
0144 struct hists *hists;
0145 struct mem_info *mem_info;
0146 struct block_info *block_info;
0147 void *raw_data;
0148 u32 raw_size;
0149 int num_res;
0150 struct res_sample *res_samples;
0151 void *trace_output;
0152 struct perf_hpp_list *hpp_list;
0153 struct hist_entry *parent_he;
0154 struct hist_entry_ops *ops;
0155 union {
0156
0157 struct {
0158 struct rb_root_cached hroot_in;
0159 struct rb_root_cached hroot_out;
0160 };
0161 struct rb_root sorted_chain;
0162 };
0163 struct callchain_root callchain[0];
0164 };
0165
0166 static __pure inline bool hist_entry__has_callchains(struct hist_entry *he)
0167 {
0168 return he->callchain_size != 0;
0169 }
0170
0171 int hist_entry__sym_snprintf(struct hist_entry *he, char *bf, size_t size, unsigned int width);
0172
0173 static inline bool hist_entry__has_pairs(struct hist_entry *he)
0174 {
0175 return !list_empty(&he->pairs.node);
0176 }
0177
0178 static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he)
0179 {
0180 if (hist_entry__has_pairs(he))
0181 return list_entry(he->pairs.node.next, struct hist_entry, pairs.node);
0182 return NULL;
0183 }
0184
0185 static inline void hist_entry__add_pair(struct hist_entry *pair,
0186 struct hist_entry *he)
0187 {
0188 list_add_tail(&pair->pairs.node, &he->pairs.head);
0189 }
0190
0191 static inline float hist_entry__get_percent_limit(struct hist_entry *he)
0192 {
0193 u64 period = he->stat.period;
0194 u64 total_period = hists__total_period(he->hists);
0195
0196 if (unlikely(total_period == 0))
0197 return 0;
0198
0199 if (symbol_conf.cumulate_callchain)
0200 period = he->stat_acc->period;
0201
0202 return period * 100.0 / total_period;
0203 }
0204
0205 enum sort_mode {
0206 SORT_MODE__NORMAL,
0207 SORT_MODE__BRANCH,
0208 SORT_MODE__MEMORY,
0209 SORT_MODE__TOP,
0210 SORT_MODE__DIFF,
0211 SORT_MODE__TRACEPOINT,
0212 };
0213
0214 enum sort_type {
0215
0216 SORT_PID,
0217 SORT_COMM,
0218 SORT_DSO,
0219 SORT_SYM,
0220 SORT_PARENT,
0221 SORT_CPU,
0222 SORT_SOCKET,
0223 SORT_SRCLINE,
0224 SORT_SRCFILE,
0225 SORT_LOCAL_WEIGHT,
0226 SORT_GLOBAL_WEIGHT,
0227 SORT_TRANSACTION,
0228 SORT_TRACE,
0229 SORT_SYM_SIZE,
0230 SORT_DSO_SIZE,
0231 SORT_CGROUP,
0232 SORT_CGROUP_ID,
0233 SORT_SYM_IPC_NULL,
0234 SORT_TIME,
0235 SORT_CODE_PAGE_SIZE,
0236 SORT_LOCAL_INS_LAT,
0237 SORT_GLOBAL_INS_LAT,
0238 SORT_LOCAL_PIPELINE_STAGE_CYC,
0239 SORT_GLOBAL_PIPELINE_STAGE_CYC,
0240
0241
0242 __SORT_BRANCH_STACK,
0243 SORT_DSO_FROM = __SORT_BRANCH_STACK,
0244 SORT_DSO_TO,
0245 SORT_SYM_FROM,
0246 SORT_SYM_TO,
0247 SORT_MISPREDICT,
0248 SORT_ABORT,
0249 SORT_IN_TX,
0250 SORT_CYCLES,
0251 SORT_SRCLINE_FROM,
0252 SORT_SRCLINE_TO,
0253 SORT_SYM_IPC,
0254 SORT_ADDR_FROM,
0255 SORT_ADDR_TO,
0256
0257
0258 __SORT_MEMORY_MODE,
0259 SORT_MEM_DADDR_SYMBOL = __SORT_MEMORY_MODE,
0260 SORT_MEM_DADDR_DSO,
0261 SORT_MEM_LOCKED,
0262 SORT_MEM_TLB,
0263 SORT_MEM_LVL,
0264 SORT_MEM_SNOOP,
0265 SORT_MEM_DCACHELINE,
0266 SORT_MEM_IADDR_SYMBOL,
0267 SORT_MEM_PHYS_DADDR,
0268 SORT_MEM_DATA_PAGE_SIZE,
0269 SORT_MEM_BLOCKED,
0270 };
0271
0272
0273
0274
0275
0276 struct sort_entry {
0277 const char *se_header;
0278
0279 int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
0280 int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
0281 int64_t (*se_sort)(struct hist_entry *, struct hist_entry *);
0282 int (*se_snprintf)(struct hist_entry *he, char *bf, size_t size,
0283 unsigned int width);
0284 int (*se_filter)(struct hist_entry *he, int type, const void *arg);
0285 u8 se_width_idx;
0286 };
0287
0288 struct block_hist {
0289 struct hists block_hists;
0290 struct perf_hpp_list block_list;
0291 struct perf_hpp_fmt block_fmt;
0292 int block_idx;
0293 bool valid;
0294 struct hist_entry he;
0295 };
0296
0297 extern struct sort_entry sort_thread;
0298 extern struct list_head hist_entry__sort_list;
0299
0300 struct evlist;
0301 struct tep_handle;
0302 int setup_sorting(struct evlist *evlist);
0303 int setup_output_field(void);
0304 void reset_output_field(void);
0305 void sort__setup_elide(FILE *fp);
0306 void perf_hpp__set_elide(int idx, bool elide);
0307
0308 char *sort_help(const char *prefix);
0309
0310 int report_parse_ignore_callees_opt(const struct option *opt, const char *arg, int unset);
0311
0312 bool is_strict_order(const char *order);
0313
0314 int hpp_dimension__add_output(unsigned col);
0315 void reset_dimensions(void);
0316 int sort_dimension__add(struct perf_hpp_list *list, const char *tok,
0317 struct evlist *evlist,
0318 int level);
0319 int output_field_add(struct perf_hpp_list *list, char *tok);
0320 int64_t
0321 sort__iaddr_cmp(struct hist_entry *left, struct hist_entry *right);
0322 int64_t
0323 sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right);
0324 int64_t
0325 sort__dcacheline_cmp(struct hist_entry *left, struct hist_entry *right);
0326 int64_t
0327 _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r);
0328 char *hist_entry__srcline(struct hist_entry *he);
0329 #endif