Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
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         /* PERF_HPP__DELTA */
0064         double  period_ratio_delta;
0065 
0066         /* PERF_HPP__RATIO */
0067         double  period_ratio;
0068 
0069         /* HISTC_WEIGHTED_DIFF */
0070         s64 wdiff;
0071 
0072         /* PERF_HPP_DIFF__CYCLES */
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  * struct hist_entry - histogram entry
0086  *
0087  * @row_offset - offset from the first callchain expanded to appear on screen
0088  * @nr_rows - rows expanded in callchain, recalculated on folding/unfolding
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     /* We are added by hists__add_dummy_entry. */
0116     bool            dummy;
0117     bool            leaf;
0118 
0119     char            level;
0120     u8          filtered;
0121 
0122     u16         callchain_size;
0123     union {
0124         /*
0125          * Since perf diff only supports the stdio output, TUI
0126          * fields are only accessed from perf report (or perf
0127          * top).  So make it a union to reduce memory usage.
0128          */
0129         struct hist_entry_diff  diff;
0130         struct /* for TUI */ {
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         /* this is for hierarchical entry structure */
0157         struct {
0158             struct rb_root_cached   hroot_in;
0159             struct rb_root_cached   hroot_out;
0160         };              /* non-leaf entries */
0161         struct rb_root  sorted_chain;   /* leaf entry has callchains */
0162     };
0163     struct callchain_root   callchain[0]; /* must be last member */
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     /* common sort keys */
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     /* branch stack specific sort keys */
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     /* memory mode specific sort keys */
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  * configurable sorting bits
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  /* __PERF_SORT_H */