^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * This is rewrite of original c2c tool introduced in here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * http://lwn.net/Articles/588866/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * The original tool was changed to fit in current perf state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Original authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Don Zickus <dzickus@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Dick Fowles <fowles@inreach.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Joe Mario <jmario@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/stringify.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sys/param.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "builtin.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <perf/cpumap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <subcmd/pager.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <subcmd/parse-options.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "map_symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "mem-events.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "hist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "sort.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include "tool.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include "cacheline.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include "data.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "event.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include "evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "ui/browsers/hists.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include "thread.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "mem2node.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "symbol.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include "ui/ui.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include "ui/progress.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include "../perf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct c2c_hists {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct hists hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct perf_hpp_list list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct c2c_stats stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct compute_stats {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct stats lcl_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct stats rmt_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) struct stats load;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct c2c_hist_entry {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct c2c_hists *hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct c2c_stats stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned long *cpuset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) unsigned long *nodeset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct c2c_stats *node_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) unsigned int cacheline_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct compute_stats cstats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned long paddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned long paddr_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) bool paddr_zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) char *nodestr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * must be at the end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * because of its callchain dynamic entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct hist_entry he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) static char const *coalesce_default = "iaddr";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct perf_c2c {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct perf_tool tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct c2c_hists hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct mem2node mem2node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) unsigned long **nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int nodes_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int cpus_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) int *cpu2node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int node_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) bool show_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) bool show_all;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) bool use_stdio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) bool stats_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) bool symbol_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) bool stitch_lbr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* HITM shared clines stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct c2c_stats hitm_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int shared_clines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int display;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) const char *coalesce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) char *cl_sort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) char *cl_resort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) char *cl_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) DISPLAY_LCL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) DISPLAY_RMT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) DISPLAY_TOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) DISPLAY_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static const char *display_str[DISPLAY_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) [DISPLAY_LCL] = "Local",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) [DISPLAY_RMT] = "Remote",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) [DISPLAY_TOT] = "Total",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static const struct option c2c_options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) OPT_INCR('v', "verbose", &verbose, "be more verbose (show counter open errors, etc)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static struct perf_c2c c2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static void *c2c_he_zalloc(size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) c2c_he = zalloc(size + sizeof(*c2c_he));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) if (!c2c_he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) c2c_he->cpuset = bitmap_alloc(c2c.cpus_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!c2c_he->cpuset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) c2c_he->nodeset = bitmap_alloc(c2c.nodes_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (!c2c_he->nodeset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) c2c_he->node_stats = zalloc(c2c.nodes_cnt * sizeof(*c2c_he->node_stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if (!c2c_he->node_stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) init_stats(&c2c_he->cstats.lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) init_stats(&c2c_he->cstats.rmt_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) init_stats(&c2c_he->cstats.load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return &c2c_he->he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static void c2c_he_free(void *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (c2c_he->hists) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) hists__delete_entries(&c2c_he->hists->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) free(c2c_he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) free(c2c_he->cpuset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) free(c2c_he->nodeset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) free(c2c_he->nodestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) free(c2c_he->node_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) free(c2c_he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static struct hist_entry_ops c2c_entry_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .new = c2c_he_zalloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) .free = c2c_he_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static int c2c_hists__init(struct c2c_hists *hists,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) const char *sort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int nr_header_lines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static struct c2c_hists*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) he__get_c2c_hists(struct hist_entry *he,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) const char *sort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) int nr_header_lines)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct c2c_hists *hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (c2c_he->hists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return c2c_he->hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) hists = c2c_he->hists = zalloc(sizeof(*hists));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (!hists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) ret = c2c_hists__init(hists, sort, nr_header_lines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) free(hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static void c2c_he__set_cpu(struct c2c_hist_entry *c2c_he,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (WARN_ONCE(sample->cpu == (unsigned int) -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) "WARNING: no sample cpu value"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) set_bit(sample->cpu, c2c_he->cpuset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) static void c2c_he__set_node(struct c2c_hist_entry *c2c_he,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) int node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!sample->phys_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) c2c_he->paddr_zero = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) node = mem2node__node(&c2c.mem2node, sample->phys_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) if (WARN_ONCE(node < 0, "WARNING: failed to find node\n"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) set_bit(node, c2c_he->nodeset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) if (c2c_he->paddr != sample->phys_addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) c2c_he->paddr_cnt++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) c2c_he->paddr = sample->phys_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static void compute_stats(struct c2c_hist_entry *c2c_he,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct c2c_stats *stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u64 weight)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct compute_stats *cstats = &c2c_he->cstats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (stats->rmt_hitm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) update_stats(&cstats->rmt_hitm, weight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) else if (stats->lcl_hitm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) update_stats(&cstats->lcl_hitm, weight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) else if (stats->load)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) update_stats(&cstats->load, weight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static int process_sample_event(struct perf_tool *tool __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) union perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct machine *machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct c2c_hists *c2c_hists = &c2c.hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct c2c_stats stats = { .nr_entries = 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct hist_entry *he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct addr_location al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct mem_info *mi, *mi_dup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (machine__resolve(machine, &al, sample) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) pr_debug("problem processing %d event, skipping it.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) event->header.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) if (c2c.stitch_lbr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) al.thread->lbr_stitch_enable = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ret = sample__resolve_callchain(sample, &callchain_cursor, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) evsel, &al, sysctl_perf_event_max_stack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) mi = sample__resolve_mem(sample, &al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (mi == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * The mi object is released in hists__add_entry_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * if it gets sorted out into existing data, so we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * to take the copy now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) mi_dup = mem_info__get(mi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) c2c_decode_stats(&stats, mi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) he = hists__add_entry_ops(&c2c_hists->hists, &c2c_entry_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) &al, NULL, NULL, mi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) sample, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (he == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto free_mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) c2c_add_stats(&c2c_he->stats, &stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) c2c_add_stats(&c2c_hists->stats, &stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) c2c_he__set_cpu(c2c_he, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) c2c_he__set_node(c2c_he, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) hists__inc_nr_samples(&c2c_hists->hists, he->filtered);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ret = hist_entry__append_callchain(he, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * There's already been warning about missing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * sample's cpu value. Let's account all to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * node 0 in this case, without any further
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * warning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * Doing node stats only for single callchain data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int cpu = sample->cpu == (unsigned int) -1 ? 0 : sample->cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) int node = c2c.cpu2node[cpu];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) mi = mi_dup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) c2c_hists = he__get_c2c_hists(he, c2c.cl_sort, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (!c2c_hists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) goto free_mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) he = hists__add_entry_ops(&c2c_hists->hists, &c2c_entry_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) &al, NULL, NULL, mi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) sample, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (he == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) goto free_mi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) c2c_add_stats(&c2c_he->stats, &stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) c2c_add_stats(&c2c_hists->stats, &stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) c2c_add_stats(&c2c_he->node_stats[node], &stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) compute_stats(c2c_he, &stats, sample->weight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) c2c_he__set_cpu(c2c_he, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) c2c_he__set_node(c2c_he, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) hists__inc_nr_samples(&c2c_hists->hists, he->filtered);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) ret = hist_entry__append_callchain(he, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) addr_location__put(&al);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) free_mi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) mem_info__put(mi_dup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) mem_info__put(mi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static struct perf_c2c c2c = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .tool = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .sample = process_sample_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) .mmap = perf_event__process_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) .mmap2 = perf_event__process_mmap2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .comm = perf_event__process_comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .exit = perf_event__process_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) .fork = perf_event__process_fork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) .lost = perf_event__process_lost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) .ordered_events = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .ordering_requires_timestamps = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static const char * const c2c_usage[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) "perf c2c {record|report}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) static const char * const __usage_report[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) "perf c2c report",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) static const char * const *report_c2c_usage = __usage_report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) #define C2C_HEADER_MAX 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct c2c_header {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) const char *text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) int span;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) } line[C2C_HEADER_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) struct c2c_dimension {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct c2c_header header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) const char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) int width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct sort_entry *se;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) int64_t (*cmp)(struct perf_hpp_fmt *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct hist_entry *, struct hist_entry *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int (*entry)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct hist_entry *he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) int (*color)(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct hist_entry *he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct c2c_fmt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) struct perf_hpp_fmt fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct c2c_dimension *dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) #define SYMBOL_WIDTH 30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static struct c2c_dimension dim_symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) static struct c2c_dimension dim_srcline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static int symbol_width(struct hists *hists, struct sort_entry *se)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) int width = hists__col_len(hists, se->se_width_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) if (!c2c.symbol_full)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) width = MIN(width, SYMBOL_WIDTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static int c2c_width(struct perf_hpp_fmt *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) struct perf_hpp *hpp __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) struct hists *hists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct c2c_fmt *c2c_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct c2c_dimension *dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) c2c_fmt = container_of(fmt, struct c2c_fmt, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) dim = c2c_fmt->dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (dim == &dim_symbol || dim == &dim_srcline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return symbol_width(hists, dim->se);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) return dim->se ? hists__col_len(hists, dim->se->se_width_idx) :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) c2c_fmt->dim->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static int c2c_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) struct hists *hists, int line, int *span)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct perf_hpp_list *hpp_list = hists->hpp_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct c2c_fmt *c2c_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct c2c_dimension *dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) const char *text = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int width = c2c_width(fmt, hpp, hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) c2c_fmt = container_of(fmt, struct c2c_fmt, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) dim = c2c_fmt->dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (dim->se) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) text = dim->header.line[line].text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Use the last line from sort_entry if not defined. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (!text && (line == hpp_list->nr_header_lines - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) text = dim->se->se_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) text = dim->header.line[line].text;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if (*span) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) (*span)--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) *span = dim->header.line[line].span;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) if (text == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) text = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) return scnprintf(hpp->buf, hpp->size, "%*s", width, text);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) #define HEX_STR(__s, __v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) scnprintf(__s, sizeof(__s), "0x%" PRIx64, __v); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) __s; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) dcacheline_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) return sort__dcacheline_cmp(left, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) static int dcacheline_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) uint64_t addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) char buf[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (he->mem_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) addr = cl_address(he->mem_info->daddr.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return scnprintf(hpp->buf, hpp->size, "%*s", width, HEX_STR(buf, addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) dcacheline_node_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (WARN_ON_ONCE(!c2c_he->nodestr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return scnprintf(hpp->buf, hpp->size, "%*s", width, c2c_he->nodestr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dcacheline_node_count(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) return scnprintf(hpp->buf, hpp->size, "%*lu", width, c2c_he->paddr_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static int offset_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) uint64_t addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) char buf[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (he->mem_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) addr = cl_offset(he->mem_info->daddr.al_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return scnprintf(hpp->buf, hpp->size, "%*s", width, HEX_STR(buf, addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) offset_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) uint64_t l = 0, r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (left->mem_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) l = cl_offset(left->mem_info->daddr.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (right->mem_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) r = cl_offset(right->mem_info->daddr.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return (int64_t)(r - l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) iaddr_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) uint64_t addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) char buf[20];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (he->mem_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) addr = he->mem_info->iaddr.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) return scnprintf(hpp->buf, hpp->size, "%*s", width, HEX_STR(buf, addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) iaddr_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return sort__iaddr_cmp(left, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) tot_hitm_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) unsigned int tot_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) tot_hitm = c2c_he->stats.lcl_hitm + c2c_he->stats.rmt_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return scnprintf(hpp->buf, hpp->size, "%*u", width, tot_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) tot_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct c2c_hist_entry *c2c_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct c2c_hist_entry *c2c_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) uint64_t tot_hitm_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) uint64_t tot_hitm_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) c2c_left = container_of(left, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) c2c_right = container_of(right, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) tot_hitm_left = c2c_left->stats.lcl_hitm + c2c_left->stats.rmt_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) tot_hitm_right = c2c_right->stats.lcl_hitm + c2c_right->stats.rmt_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return tot_hitm_left - tot_hitm_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) #define STAT_FN_ENTRY(__f) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) static int \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) __f ## _entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) struct hist_entry *he) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) struct c2c_hist_entry *c2c_he; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) int width = c2c_width(fmt, hpp, he->hists); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) c2c_he = container_of(he, struct c2c_hist_entry, he); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return scnprintf(hpp->buf, hpp->size, "%*u", width, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) c2c_he->stats.__f); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) #define STAT_FN_CMP(__f) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static int64_t \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) __f ## _cmp(struct perf_hpp_fmt *fmt __maybe_unused, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct hist_entry *left, struct hist_entry *right) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct c2c_hist_entry *c2c_left, *c2c_right; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) c2c_left = container_of(left, struct c2c_hist_entry, he); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) c2c_right = container_of(right, struct c2c_hist_entry, he); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) return (uint64_t) c2c_left->stats.__f - \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) (uint64_t) c2c_right->stats.__f; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) #define STAT_FN(__f) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) STAT_FN_ENTRY(__f) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) STAT_FN_CMP(__f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) STAT_FN(rmt_hitm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) STAT_FN(lcl_hitm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) STAT_FN(store)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) STAT_FN(st_l1hit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) STAT_FN(st_l1miss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) STAT_FN(ld_fbhit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) STAT_FN(ld_l1hit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) STAT_FN(ld_l2hit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) STAT_FN(ld_llchit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) STAT_FN(rmt_hit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static uint64_t total_records(struct c2c_stats *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) uint64_t lclmiss, ldcnt, total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) lclmiss = stats->lcl_dram +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) stats->rmt_dram +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) stats->rmt_hitm +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) stats->rmt_hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) ldcnt = lclmiss +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) stats->ld_fbhit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) stats->ld_l1hit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) stats->ld_l2hit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) stats->ld_llchit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) stats->lcl_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) total = ldcnt +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) stats->st_l1hit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) stats->st_l1miss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) return total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) tot_recs_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) uint64_t tot_recs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) tot_recs = total_records(&c2c_he->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return scnprintf(hpp->buf, hpp->size, "%*" PRIu64, width, tot_recs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) tot_recs_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct c2c_hist_entry *c2c_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct c2c_hist_entry *c2c_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) uint64_t tot_recs_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) uint64_t tot_recs_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) c2c_left = container_of(left, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) c2c_right = container_of(right, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) tot_recs_left = total_records(&c2c_left->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) tot_recs_right = total_records(&c2c_right->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) return tot_recs_left - tot_recs_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) static uint64_t total_loads(struct c2c_stats *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) uint64_t lclmiss, ldcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) lclmiss = stats->lcl_dram +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) stats->rmt_dram +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) stats->rmt_hitm +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) stats->rmt_hit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ldcnt = lclmiss +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) stats->ld_fbhit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) stats->ld_l1hit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) stats->ld_l2hit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) stats->ld_llchit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) stats->lcl_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return ldcnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) tot_loads_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) uint64_t tot_recs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) tot_recs = total_loads(&c2c_he->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return scnprintf(hpp->buf, hpp->size, "%*" PRIu64, width, tot_recs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) tot_loads_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct c2c_hist_entry *c2c_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct c2c_hist_entry *c2c_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) uint64_t tot_recs_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) uint64_t tot_recs_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) c2c_left = container_of(left, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) c2c_right = container_of(right, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) tot_recs_left = total_loads(&c2c_left->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) tot_recs_right = total_loads(&c2c_right->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) return tot_recs_left - tot_recs_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) typedef double (get_percent_cb)(struct c2c_hist_entry *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) percent_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct hist_entry *he, get_percent_cb get_percent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) double per;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) per = get_percent(c2c_he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) #ifdef HAVE_SLANG_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) if (use_browser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return __hpp__slsmg_color_printf(hpp, "%*.2f%%", width - 1, per);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return hpp_color_scnprintf(hpp, "%*.2f%%", width - 1, per);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) static double percent_hitm(struct c2c_hist_entry *c2c_he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct c2c_hists *hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct c2c_stats *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) struct c2c_stats *total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) int tot = 0, st = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) double p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) hists = container_of(c2c_he->he.hists, struct c2c_hists, hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) stats = &c2c_he->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) total = &hists->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) switch (c2c.display) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) case DISPLAY_RMT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) st = stats->rmt_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) tot = total->rmt_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) case DISPLAY_LCL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) st = stats->lcl_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) tot = total->lcl_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) case DISPLAY_TOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) st = stats->tot_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) tot = total->tot_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) p = tot ? (double) st / tot : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return 100 * p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) #define PERC_STR(__s, __v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) scnprintf(__s, sizeof(__s), "%.2F%%", __v); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) __s; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) percent_hitm_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) char buf[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) double per;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) per = percent_hitm(c2c_he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) percent_hitm_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return percent_color(fmt, hpp, he, percent_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) percent_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) struct c2c_hist_entry *c2c_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct c2c_hist_entry *c2c_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) double per_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) double per_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) c2c_left = container_of(left, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) c2c_right = container_of(right, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) per_left = percent_hitm(c2c_left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) per_right = percent_hitm(c2c_right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return per_left - per_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) static struct c2c_stats *he_stats(struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return &c2c_he->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) static struct c2c_stats *total_stats(struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) struct c2c_hists *hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) hists = container_of(he->hists, struct c2c_hists, hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return &hists->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static double percent(int st, int tot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return tot ? 100. * (double) st / (double) tot : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) #define PERCENT(__h, __f) percent(he_stats(__h)->__f, total_stats(__h)->__f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) #define PERCENT_FN(__f) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static double percent_ ## __f(struct c2c_hist_entry *c2c_he) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct c2c_hists *hists; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) hists = container_of(c2c_he->he.hists, struct c2c_hists, hists); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return percent(c2c_he->stats.__f, hists->stats.__f); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) PERCENT_FN(rmt_hitm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) PERCENT_FN(lcl_hitm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) PERCENT_FN(st_l1hit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) PERCENT_FN(st_l1miss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) percent_rmt_hitm_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) double per = PERCENT(he, rmt_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) char buf[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) percent_rmt_hitm_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return percent_color(fmt, hpp, he, percent_rmt_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) percent_rmt_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) double per_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) double per_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) per_left = PERCENT(left, lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) per_right = PERCENT(right, lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return per_left - per_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) percent_lcl_hitm_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) double per = PERCENT(he, lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) char buf[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) percent_lcl_hitm_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return percent_color(fmt, hpp, he, percent_lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) percent_lcl_hitm_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) double per_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) double per_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) per_left = PERCENT(left, lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) per_right = PERCENT(right, lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) return per_left - per_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) percent_stores_l1hit_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) double per = PERCENT(he, st_l1hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) char buf[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) percent_stores_l1hit_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return percent_color(fmt, hpp, he, percent_st_l1hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) percent_stores_l1hit_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) double per_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) double per_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) per_left = PERCENT(left, st_l1hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) per_right = PERCENT(right, st_l1hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) return per_left - per_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) percent_stores_l1miss_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) double per = PERCENT(he, st_l1miss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) char buf[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return scnprintf(hpp->buf, hpp->size, "%*s", width, PERC_STR(buf, per));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) percent_stores_l1miss_color(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return percent_color(fmt, hpp, he, percent_st_l1miss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) percent_stores_l1miss_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) double per_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) double per_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) per_left = PERCENT(left, st_l1miss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) per_right = PERCENT(right, st_l1miss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return per_left - per_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) STAT_FN(lcl_dram)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) STAT_FN(rmt_dram)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) pid_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return scnprintf(hpp->buf, hpp->size, "%*d", width, he->thread->pid_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) pid_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) struct hist_entry *left, struct hist_entry *right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return left->thread->pid_ - right->thread->pid_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) static int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) empty_cmp(struct perf_hpp_fmt *fmt __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) struct hist_entry *left __maybe_unused,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) struct hist_entry *right __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) node_entry(struct perf_hpp_fmt *fmt __maybe_unused, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) bool first = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) int node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) for (node = 0; node < c2c.nodes_cnt; node++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) DECLARE_BITMAP(set, c2c.cpus_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) bitmap_zero(set, c2c.cpus_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) bitmap_and(set, c2c_he->cpuset, c2c.nodes[node], c2c.cpus_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (!bitmap_weight(set, c2c.cpus_cnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (c2c.node_info == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) ret = scnprintf(hpp->buf, hpp->size, "%21s", " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) advance_hpp(hpp, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) if (!first) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) ret = scnprintf(hpp->buf, hpp->size, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) advance_hpp(hpp, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) switch (c2c.node_info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) ret = scnprintf(hpp->buf, hpp->size, "%2d", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) advance_hpp(hpp, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) int num = bitmap_weight(set, c2c.cpus_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) struct c2c_stats *stats = &c2c_he->node_stats[node];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) ret = scnprintf(hpp->buf, hpp->size, "%2d{%2d ", node, num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) advance_hpp(hpp, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) #define DISPLAY_HITM(__h) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (c2c_he->stats.__h> 0) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) ret = scnprintf(hpp->buf, hpp->size, "%5.1f%% ", \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) percent(stats->__h, c2c_he->stats.__h));\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) } else { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) ret = scnprintf(hpp->buf, hpp->size, "%6s ", "n/a"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) switch (c2c.display) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) case DISPLAY_RMT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) DISPLAY_HITM(rmt_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) case DISPLAY_LCL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) DISPLAY_HITM(lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) case DISPLAY_TOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) DISPLAY_HITM(tot_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) #undef DISPLAY_HITM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) advance_hpp(hpp, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) if (c2c_he->stats.store > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) ret = scnprintf(hpp->buf, hpp->size, "%5.1f%%}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) percent(stats->store, c2c_he->stats.store));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ret = scnprintf(hpp->buf, hpp->size, "%6s}", "n/a");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) advance_hpp(hpp, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) ret = scnprintf(hpp->buf, hpp->size, "%2d{", node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) advance_hpp(hpp, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) ret = bitmap_scnprintf(set, c2c.cpus_cnt, hpp->buf, hpp->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) advance_hpp(hpp, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) ret = scnprintf(hpp->buf, hpp->size, "}");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) advance_hpp(hpp, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) first = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) mean_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) struct hist_entry *he, double mean)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) char buf[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) scnprintf(buf, 10, "%6.0f", mean);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) return scnprintf(hpp->buf, hpp->size, "%*s", width, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) #define MEAN_ENTRY(__func, __val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) static int \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) __func(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, struct hist_entry *he) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) struct c2c_hist_entry *c2c_he; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) c2c_he = container_of(he, struct c2c_hist_entry, he); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) return mean_entry(fmt, hpp, he, avg_stats(&c2c_he->cstats.__val)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) MEAN_ENTRY(mean_rmt_entry, rmt_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) MEAN_ENTRY(mean_lcl_entry, lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) MEAN_ENTRY(mean_load_entry, load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) cpucnt_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) char buf[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) scnprintf(buf, 10, "%d", bitmap_weight(c2c_he->cpuset, c2c.cpus_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return scnprintf(hpp->buf, hpp->size, "%*s", width, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) cl_idx_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) char buf[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) scnprintf(buf, 10, "%u", c2c_he->cacheline_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return scnprintf(hpp->buf, hpp->size, "%*s", width, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) cl_idx_empty_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) int width = c2c_width(fmt, hpp, he->hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return scnprintf(hpp->buf, hpp->size, "%*s", width, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) #define HEADER_LOW(__h) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) .line[1] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) .text = __h, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) #define HEADER_BOTH(__h0, __h1) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .line[0] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) .text = __h0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) .line[1] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) .text = __h1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) #define HEADER_SPAN(__h0, __h1, __s) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) .line[0] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) .text = __h0, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) .span = __s, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) .line[1] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) .text = __h1, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) #define HEADER_SPAN_LOW(__h) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) .line[1] = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) .text = __h, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) static struct c2c_dimension dim_dcacheline = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) .header = HEADER_SPAN("--- Cacheline ----", "Address", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) .name = "dcacheline",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) .cmp = dcacheline_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) .entry = dcacheline_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) .width = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static struct c2c_dimension dim_dcacheline_node = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) .header = HEADER_LOW("Node"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) .name = "dcacheline_node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) .cmp = empty_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) .entry = dcacheline_node_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) .width = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) static struct c2c_dimension dim_dcacheline_count = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) .header = HEADER_LOW("PA cnt"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) .name = "dcacheline_count",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) .cmp = empty_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) .entry = dcacheline_node_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) .width = 6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) static struct c2c_header header_offset_tui = HEADER_SPAN("-----", "Off", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) static struct c2c_dimension dim_offset = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) .header = HEADER_SPAN("--- Data address -", "Offset", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) .name = "offset",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) .cmp = offset_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) .entry = offset_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) .width = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) static struct c2c_dimension dim_offset_node = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) .header = HEADER_LOW("Node"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) .name = "offset_node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) .cmp = empty_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) .entry = dcacheline_node_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) .width = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) static struct c2c_dimension dim_iaddr = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) .header = HEADER_LOW("Code address"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) .name = "iaddr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) .cmp = iaddr_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) .entry = iaddr_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) .width = 18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) static struct c2c_dimension dim_tot_hitm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) .header = HEADER_SPAN("------- Load Hitm -------", "Total", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) .name = "tot_hitm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) .cmp = tot_hitm_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) .entry = tot_hitm_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) static struct c2c_dimension dim_lcl_hitm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) .header = HEADER_SPAN_LOW("LclHitm"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) .name = "lcl_hitm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) .cmp = lcl_hitm_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) .entry = lcl_hitm_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) static struct c2c_dimension dim_rmt_hitm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) .header = HEADER_SPAN_LOW("RmtHitm"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) .name = "rmt_hitm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) .cmp = rmt_hitm_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) .entry = rmt_hitm_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) static struct c2c_dimension dim_cl_rmt_hitm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) .header = HEADER_SPAN("----- HITM -----", "Rmt", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) .name = "cl_rmt_hitm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) .cmp = rmt_hitm_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) .entry = rmt_hitm_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) static struct c2c_dimension dim_cl_lcl_hitm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) .header = HEADER_SPAN_LOW("Lcl"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) .name = "cl_lcl_hitm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) .cmp = lcl_hitm_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) .entry = lcl_hitm_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) static struct c2c_dimension dim_tot_stores = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) .header = HEADER_BOTH("Total", "Stores"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) .name = "tot_stores",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) .cmp = store_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) .entry = store_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) static struct c2c_dimension dim_stores_l1hit = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) .header = HEADER_SPAN("---- Stores ----", "L1Hit", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) .name = "stores_l1hit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) .cmp = st_l1hit_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) .entry = st_l1hit_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) static struct c2c_dimension dim_stores_l1miss = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) .header = HEADER_SPAN_LOW("L1Miss"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) .name = "stores_l1miss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) .cmp = st_l1miss_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) .entry = st_l1miss_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) static struct c2c_dimension dim_cl_stores_l1hit = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) .header = HEADER_SPAN("-- Store Refs --", "L1 Hit", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) .name = "cl_stores_l1hit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) .cmp = st_l1hit_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) .entry = st_l1hit_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static struct c2c_dimension dim_cl_stores_l1miss = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) .header = HEADER_SPAN_LOW("L1 Miss"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) .name = "cl_stores_l1miss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) .cmp = st_l1miss_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) .entry = st_l1miss_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) static struct c2c_dimension dim_ld_fbhit = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) .header = HEADER_SPAN("----- Core Load Hit -----", "FB", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) .name = "ld_fbhit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) .cmp = ld_fbhit_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) .entry = ld_fbhit_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) static struct c2c_dimension dim_ld_l1hit = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) .header = HEADER_SPAN_LOW("L1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) .name = "ld_l1hit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) .cmp = ld_l1hit_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) .entry = ld_l1hit_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static struct c2c_dimension dim_ld_l2hit = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) .header = HEADER_SPAN_LOW("L2"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) .name = "ld_l2hit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) .cmp = ld_l2hit_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) .entry = ld_l2hit_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) static struct c2c_dimension dim_ld_llchit = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) .header = HEADER_SPAN("- LLC Load Hit --", "LclHit", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) .name = "ld_lclhit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) .cmp = ld_llchit_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) .entry = ld_llchit_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) .width = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) static struct c2c_dimension dim_ld_rmthit = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) .header = HEADER_SPAN("- RMT Load Hit --", "RmtHit", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) .name = "ld_rmthit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) .cmp = rmt_hit_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) .entry = rmt_hit_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) .width = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) static struct c2c_dimension dim_tot_recs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) .header = HEADER_BOTH("Total", "records"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) .name = "tot_recs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) .cmp = tot_recs_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) .entry = tot_recs_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) static struct c2c_dimension dim_tot_loads = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) .header = HEADER_BOTH("Total", "Loads"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) .name = "tot_loads",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) .cmp = tot_loads_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) .entry = tot_loads_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) static struct c2c_header percent_hitm_header[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) [DISPLAY_LCL] = HEADER_BOTH("Lcl", "Hitm"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) [DISPLAY_RMT] = HEADER_BOTH("Rmt", "Hitm"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) [DISPLAY_TOT] = HEADER_BOTH("Tot", "Hitm"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) static struct c2c_dimension dim_percent_hitm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) .name = "percent_hitm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) .cmp = percent_hitm_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) .entry = percent_hitm_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) .color = percent_hitm_color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) static struct c2c_dimension dim_percent_rmt_hitm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) .header = HEADER_SPAN("----- HITM -----", "RmtHitm", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) .name = "percent_rmt_hitm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) .cmp = percent_rmt_hitm_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) .entry = percent_rmt_hitm_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) .color = percent_rmt_hitm_color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) static struct c2c_dimension dim_percent_lcl_hitm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) .header = HEADER_SPAN_LOW("LclHitm"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) .name = "percent_lcl_hitm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) .cmp = percent_lcl_hitm_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) .entry = percent_lcl_hitm_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) .color = percent_lcl_hitm_color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) static struct c2c_dimension dim_percent_stores_l1hit = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) .header = HEADER_SPAN("-- Store Refs --", "L1 Hit", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) .name = "percent_stores_l1hit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) .cmp = percent_stores_l1hit_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) .entry = percent_stores_l1hit_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) .color = percent_stores_l1hit_color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) static struct c2c_dimension dim_percent_stores_l1miss = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) .header = HEADER_SPAN_LOW("L1 Miss"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) .name = "percent_stores_l1miss",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) .cmp = percent_stores_l1miss_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) .entry = percent_stores_l1miss_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) .color = percent_stores_l1miss_color,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) static struct c2c_dimension dim_dram_lcl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) .header = HEADER_SPAN("--- Load Dram ----", "Lcl", 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) .name = "dram_lcl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) .cmp = lcl_dram_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) .entry = lcl_dram_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) .width = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) static struct c2c_dimension dim_dram_rmt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) .header = HEADER_SPAN_LOW("Rmt"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) .name = "dram_rmt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) .cmp = rmt_dram_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) .entry = rmt_dram_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) .width = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) static struct c2c_dimension dim_pid = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) .header = HEADER_LOW("Pid"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) .name = "pid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) .cmp = pid_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) .entry = pid_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) .width = 7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) static struct c2c_dimension dim_tid = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) .header = HEADER_LOW("Tid"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) .name = "tid",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) .se = &sort_thread,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) static struct c2c_dimension dim_symbol = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) .name = "symbol",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) .se = &sort_sym,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) static struct c2c_dimension dim_dso = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) .header = HEADER_BOTH("Shared", "Object"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) .name = "dso",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) .se = &sort_dso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) static struct c2c_header header_node[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) HEADER_LOW("Node"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) HEADER_LOW("Node{cpus %hitms %stores}"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) HEADER_LOW("Node{cpu list}"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) static struct c2c_dimension dim_node = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) .name = "node",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) .cmp = empty_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) .entry = node_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) .width = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) static struct c2c_dimension dim_mean_rmt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) .header = HEADER_SPAN("---------- cycles ----------", "rmt hitm", 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) .name = "mean_rmt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) .cmp = empty_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) .entry = mean_rmt_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) .width = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) static struct c2c_dimension dim_mean_lcl = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) .header = HEADER_SPAN_LOW("lcl hitm"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) .name = "mean_lcl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) .cmp = empty_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) .entry = mean_lcl_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) .width = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) static struct c2c_dimension dim_mean_load = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) .header = HEADER_SPAN_LOW("load"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) .name = "mean_load",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) .cmp = empty_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) .entry = mean_load_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) .width = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) static struct c2c_dimension dim_cpucnt = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) .header = HEADER_BOTH("cpu", "cnt"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) .name = "cpucnt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) .cmp = empty_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) .entry = cpucnt_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) .width = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) static struct c2c_dimension dim_srcline = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) .name = "cl_srcline",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) .se = &sort_srcline,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) static struct c2c_dimension dim_dcacheline_idx = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) .header = HEADER_LOW("Index"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) .name = "cl_idx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) .cmp = empty_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) .entry = cl_idx_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) .width = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) static struct c2c_dimension dim_dcacheline_num = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) .header = HEADER_LOW("Num"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) .name = "cl_num",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) .cmp = empty_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) .entry = cl_idx_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) .width = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) static struct c2c_dimension dim_dcacheline_num_empty = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) .header = HEADER_LOW("Num"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) .name = "cl_num_empty",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) .cmp = empty_cmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) .entry = cl_idx_empty_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) .width = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) static struct c2c_dimension *dimensions[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) &dim_dcacheline,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) &dim_dcacheline_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) &dim_dcacheline_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) &dim_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) &dim_offset_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) &dim_iaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) &dim_tot_hitm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) &dim_lcl_hitm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) &dim_rmt_hitm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) &dim_cl_lcl_hitm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) &dim_cl_rmt_hitm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) &dim_tot_stores,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) &dim_stores_l1hit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) &dim_stores_l1miss,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) &dim_cl_stores_l1hit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) &dim_cl_stores_l1miss,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) &dim_ld_fbhit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) &dim_ld_l1hit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) &dim_ld_l2hit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) &dim_ld_llchit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) &dim_ld_rmthit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) &dim_tot_recs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) &dim_tot_loads,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) &dim_percent_hitm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) &dim_percent_rmt_hitm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) &dim_percent_lcl_hitm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) &dim_percent_stores_l1hit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) &dim_percent_stores_l1miss,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) &dim_dram_lcl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) &dim_dram_rmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) &dim_pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) &dim_tid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) &dim_symbol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) &dim_dso,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) &dim_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) &dim_mean_rmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) &dim_mean_lcl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) &dim_mean_load,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) &dim_cpucnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) &dim_srcline,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) &dim_dcacheline_idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) &dim_dcacheline_num,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) &dim_dcacheline_num_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) static void fmt_free(struct perf_hpp_fmt *fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) struct c2c_fmt *c2c_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) c2c_fmt = container_of(fmt, struct c2c_fmt, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) free(c2c_fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) static bool fmt_equal(struct perf_hpp_fmt *a, struct perf_hpp_fmt *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) struct c2c_fmt *c2c_a = container_of(a, struct c2c_fmt, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) struct c2c_fmt *c2c_b = container_of(b, struct c2c_fmt, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) return c2c_a->dim == c2c_b->dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) static struct c2c_dimension *get_dimension(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) for (i = 0; dimensions[i]; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) struct c2c_dimension *dim = dimensions[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (!strcmp(dim->name, name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) return dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) static int c2c_se_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) struct c2c_fmt *c2c_fmt = container_of(fmt, struct c2c_fmt, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) struct c2c_dimension *dim = c2c_fmt->dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) size_t len = fmt->user_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (!len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) len = hists__col_len(he->hists, dim->se->se_width_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) if (dim == &dim_symbol || dim == &dim_srcline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) len = symbol_width(he->hists, dim->se);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) return dim->se->se_snprintf(he, hpp->buf, hpp->size, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) static int64_t c2c_se_cmp(struct perf_hpp_fmt *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) struct hist_entry *a, struct hist_entry *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) struct c2c_fmt *c2c_fmt = container_of(fmt, struct c2c_fmt, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) struct c2c_dimension *dim = c2c_fmt->dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) return dim->se->se_cmp(a, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) static int64_t c2c_se_collapse(struct perf_hpp_fmt *fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) struct hist_entry *a, struct hist_entry *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) struct c2c_fmt *c2c_fmt = container_of(fmt, struct c2c_fmt, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) struct c2c_dimension *dim = c2c_fmt->dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) int64_t (*collapse_fn)(struct hist_entry *, struct hist_entry *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) collapse_fn = dim->se->se_collapse ?: dim->se->se_cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) return collapse_fn(a, b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) static struct c2c_fmt *get_format(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) struct c2c_dimension *dim = get_dimension(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) struct c2c_fmt *c2c_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) struct perf_hpp_fmt *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (!dim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) c2c_fmt = zalloc(sizeof(*c2c_fmt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) if (!c2c_fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) c2c_fmt->dim = dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) fmt = &c2c_fmt->fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) INIT_LIST_HEAD(&fmt->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) INIT_LIST_HEAD(&fmt->sort_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) fmt->cmp = dim->se ? c2c_se_cmp : dim->cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) fmt->sort = dim->se ? c2c_se_cmp : dim->cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) fmt->color = dim->se ? NULL : dim->color;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) fmt->entry = dim->se ? c2c_se_entry : dim->entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) fmt->header = c2c_header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) fmt->width = c2c_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) fmt->collapse = dim->se ? c2c_se_collapse : dim->cmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) fmt->equal = fmt_equal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) fmt->free = fmt_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) return c2c_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) static int c2c_hists__init_output(struct perf_hpp_list *hpp_list, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) struct c2c_fmt *c2c_fmt = get_format(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) if (!c2c_fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) reset_dimensions();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) return output_field_add(hpp_list, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) perf_hpp_list__column_register(hpp_list, &c2c_fmt->fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) static int c2c_hists__init_sort(struct perf_hpp_list *hpp_list, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) struct c2c_fmt *c2c_fmt = get_format(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) struct c2c_dimension *dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) if (!c2c_fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) reset_dimensions();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) return sort_dimension__add(hpp_list, name, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) dim = c2c_fmt->dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) if (dim == &dim_dso)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) hpp_list->dso = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) perf_hpp_list__register_sort_field(hpp_list, &c2c_fmt->fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) #define PARSE_LIST(_list, _fn) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) char *tmp, *tok; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) ret = 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) if (!_list) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) for (tok = strtok_r((char *)_list, ", ", &tmp); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) tok; tok = strtok_r(NULL, ", ", &tmp)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) ret = _fn(hpp_list, tok); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) if (ret == -EINVAL) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) pr_err("Invalid --fields key: `%s'", tok); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) } else if (ret == -ESRCH) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) pr_err("Unknown --fields key: `%s'", tok); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) static int hpp_list__parse(struct perf_hpp_list *hpp_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) const char *output_,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) const char *sort_)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) char *output = output_ ? strdup(output_) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) char *sort = sort_ ? strdup(sort_) : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) PARSE_LIST(output, c2c_hists__init_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) PARSE_LIST(sort, c2c_hists__init_sort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) /* copy sort keys to output fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) perf_hpp__setup_output_field(hpp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) * We dont need other sorting keys other than those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) * we already specified. It also really slows down
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) * the processing a lot with big number of output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) * fields, so switching this off for c2c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) /* and then copy output fields to sort keys */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) perf_hpp__append_sort_keys(&hists->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) free(output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) free(sort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) static int c2c_hists__init(struct c2c_hists *hists,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) const char *sort,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) int nr_header_lines)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) __hists__init(&hists->hists, &hists->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) * Initialize only with sort fields, we need to resort
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) * later anyway, and that's where we add output fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) * as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) perf_hpp_list__init(&hists->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) /* Overload number of header lines.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) hists->list.nr_header_lines = nr_header_lines;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) return hpp_list__parse(&hists->list, NULL, sort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) static int c2c_hists__reinit(struct c2c_hists *c2c_hists,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) const char *output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) const char *sort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) perf_hpp__reset_output_field(&c2c_hists->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) return hpp_list__parse(&c2c_hists->list, output, sort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) #define DISPLAY_LINE_LIMIT 0.001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) static bool he__display(struct hist_entry *he, struct c2c_stats *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) double ld_dist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (c2c.show_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) #define FILTER_HITM(__h) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) if (stats->__h) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) ld_dist = ((double)c2c_he->stats.__h / stats->__h); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (ld_dist < DISPLAY_LINE_LIMIT) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) he->filtered = HIST_FILTER__C2C; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) } else { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) he->filtered = HIST_FILTER__C2C; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) switch (c2c.display) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) case DISPLAY_LCL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) FILTER_HITM(lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) case DISPLAY_RMT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) FILTER_HITM(rmt_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) case DISPLAY_TOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) FILTER_HITM(tot_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) #undef FILTER_HITM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) return he->filtered == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) static inline int valid_hitm_or_store(struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) bool has_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) has_hitm = c2c.display == DISPLAY_TOT ? c2c_he->stats.tot_hitm :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) c2c.display == DISPLAY_LCL ? c2c_he->stats.lcl_hitm :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) c2c_he->stats.rmt_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) return has_hitm || c2c_he->stats.store;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) static void set_node_width(struct c2c_hist_entry *c2c_he, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) struct c2c_dimension *dim;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) dim = &c2c.hists == c2c_he->hists ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) &dim_dcacheline_node : &dim_offset_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) if (len > dim->width)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) dim->width = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) static int set_nodestr(struct c2c_hist_entry *c2c_he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) char buf[30];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) if (c2c_he->nodestr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) if (bitmap_weight(c2c_he->nodeset, c2c.nodes_cnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) len = bitmap_scnprintf(c2c_he->nodeset, c2c.nodes_cnt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) len = scnprintf(buf, sizeof(buf), "N/A");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) set_node_width(c2c_he, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) c2c_he->nodestr = strdup(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) return c2c_he->nodestr ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) static void calc_width(struct c2c_hist_entry *c2c_he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) struct c2c_hists *c2c_hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) c2c_hists = container_of(c2c_he->he.hists, struct c2c_hists, hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) hists__calc_col_len(&c2c_hists->hists, &c2c_he->he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) set_nodestr(c2c_he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) static int filter_cb(struct hist_entry *he, void *arg __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) if (c2c.show_src && !he->srcline)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) he->srcline = hist_entry__srcline(he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) calc_width(c2c_he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) if (!valid_hitm_or_store(he))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) he->filtered = HIST_FILTER__C2C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) static int resort_cl_cb(struct hist_entry *he, void *arg __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) struct c2c_hists *c2c_hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) bool display = he__display(he, &c2c.hitm_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) c2c_hists = c2c_he->hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) if (display && c2c_hists) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) static unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) c2c_he->cacheline_idx = idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) calc_width(c2c_he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) c2c_hists__reinit(c2c_hists, c2c.cl_output, c2c.cl_resort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) hists__collapse_resort(&c2c_hists->hists, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) hists__output_resort_cb(&c2c_hists->hists, NULL, filter_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) static void setup_nodes_header(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) dim_node.header = header_node[c2c.node_info];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) static int setup_nodes(struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) struct numa_node *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) unsigned long **nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) int node, cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) int *cpu2node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) if (c2c.node_info > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) c2c.node_info = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) c2c.nodes_cnt = session->header.env.nr_numa_nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) c2c.cpus_cnt = session->header.env.nr_cpus_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) n = session->header.env.numa_nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) if (!n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) nodes = zalloc(sizeof(unsigned long *) * c2c.nodes_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) if (!nodes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) c2c.nodes = nodes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) cpu2node = zalloc(sizeof(int) * c2c.cpus_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) if (!cpu2node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) for (cpu = 0; cpu < c2c.cpus_cnt; cpu++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) cpu2node[cpu] = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) c2c.cpu2node = cpu2node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) for (node = 0; node < c2c.nodes_cnt; node++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) struct perf_cpu_map *map = n[node].map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) unsigned long *set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) set = bitmap_alloc(c2c.cpus_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) if (!set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) nodes[node] = set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) /* empty node, skip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) if (perf_cpu_map__empty(map))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) for (cpu = 0; cpu < map->nr; cpu++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) set_bit(map->map[cpu], set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) if (WARN_ONCE(cpu2node[map->map[cpu]] != -1, "node/cpu topology bug"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) cpu2node[map->map[cpu]] = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) setup_nodes_header();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) #define HAS_HITMS(__h) ((__h)->stats.lcl_hitm || (__h)->stats.rmt_hitm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) static int resort_hitm_cb(struct hist_entry *he, void *arg __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) if (HAS_HITMS(c2c_he)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) c2c.shared_clines++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) c2c_add_stats(&c2c.hitm_stats, &c2c_he->stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) static int hists__iterate_cb(struct hists *hists, hists__resort_cb_t cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) struct rb_node *next = rb_first_cached(&hists->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) while (next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) struct hist_entry *he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) he = rb_entry(next, struct hist_entry, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) ret = cb(he, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) next = rb_next(&he->rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) static void print_c2c__display_stats(FILE *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) int llc_misses;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) struct c2c_stats *stats = &c2c.hists.stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) llc_misses = stats->lcl_dram +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) stats->rmt_dram +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) stats->rmt_hit +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) stats->rmt_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) fprintf(out, "=================================================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) fprintf(out, " Trace Event Information \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) fprintf(out, "=================================================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) fprintf(out, " Total records : %10d\n", stats->nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) fprintf(out, " Locked Load/Store Operations : %10d\n", stats->locks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) fprintf(out, " Load Operations : %10d\n", stats->load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) fprintf(out, " Loads - uncacheable : %10d\n", stats->ld_uncache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) fprintf(out, " Loads - IO : %10d\n", stats->ld_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) fprintf(out, " Loads - Miss : %10d\n", stats->ld_miss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) fprintf(out, " Loads - no mapping : %10d\n", stats->ld_noadrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) fprintf(out, " Load Fill Buffer Hit : %10d\n", stats->ld_fbhit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) fprintf(out, " Load L1D hit : %10d\n", stats->ld_l1hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) fprintf(out, " Load L2D hit : %10d\n", stats->ld_l2hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) fprintf(out, " Load LLC hit : %10d\n", stats->ld_llchit + stats->lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) fprintf(out, " Load Local HITM : %10d\n", stats->lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) fprintf(out, " Load Remote HITM : %10d\n", stats->rmt_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) fprintf(out, " Load Remote HIT : %10d\n", stats->rmt_hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) fprintf(out, " Load Local DRAM : %10d\n", stats->lcl_dram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) fprintf(out, " Load Remote DRAM : %10d\n", stats->rmt_dram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) fprintf(out, " Load MESI State Exclusive : %10d\n", stats->ld_excl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) fprintf(out, " Load MESI State Shared : %10d\n", stats->ld_shared);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) fprintf(out, " Load LLC Misses : %10d\n", llc_misses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) fprintf(out, " LLC Misses to Local DRAM : %10.1f%%\n", ((double)stats->lcl_dram/(double)llc_misses) * 100.);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) fprintf(out, " LLC Misses to Remote DRAM : %10.1f%%\n", ((double)stats->rmt_dram/(double)llc_misses) * 100.);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) fprintf(out, " LLC Misses to Remote cache (HIT) : %10.1f%%\n", ((double)stats->rmt_hit /(double)llc_misses) * 100.);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) fprintf(out, " LLC Misses to Remote cache (HITM) : %10.1f%%\n", ((double)stats->rmt_hitm/(double)llc_misses) * 100.);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) fprintf(out, " Store Operations : %10d\n", stats->store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) fprintf(out, " Store - uncacheable : %10d\n", stats->st_uncache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) fprintf(out, " Store - no mapping : %10d\n", stats->st_noadrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) fprintf(out, " Store L1D Hit : %10d\n", stats->st_l1hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) fprintf(out, " Store L1D Miss : %10d\n", stats->st_l1miss);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) fprintf(out, " No Page Map Rejects : %10d\n", stats->nomap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) fprintf(out, " Unable to parse data source : %10d\n", stats->noparse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) static void print_shared_cacheline_info(FILE *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) struct c2c_stats *stats = &c2c.hitm_stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) int hitm_cnt = stats->lcl_hitm + stats->rmt_hitm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) fprintf(out, "=================================================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) fprintf(out, " Global Shared Cache Line Event Information \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) fprintf(out, "=================================================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) fprintf(out, " Total Shared Cache Lines : %10d\n", c2c.shared_clines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) fprintf(out, " Load HITs on shared lines : %10d\n", stats->load);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) fprintf(out, " Fill Buffer Hits on shared lines : %10d\n", stats->ld_fbhit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) fprintf(out, " L1D hits on shared lines : %10d\n", stats->ld_l1hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) fprintf(out, " L2D hits on shared lines : %10d\n", stats->ld_l2hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) fprintf(out, " LLC hits on shared lines : %10d\n", stats->ld_llchit + stats->lcl_hitm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) fprintf(out, " Locked Access on shared lines : %10d\n", stats->locks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) fprintf(out, " Store HITs on shared lines : %10d\n", stats->store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) fprintf(out, " Store L1D hits on shared lines : %10d\n", stats->st_l1hit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) fprintf(out, " Total Merged records : %10d\n", hitm_cnt + stats->store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) static void print_cacheline(struct c2c_hists *c2c_hists,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) struct hist_entry *he_cl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) struct perf_hpp_list *hpp_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) FILE *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) char bf[1000];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) struct perf_hpp hpp = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) .buf = bf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) .size = 1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) static bool once;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) if (!once) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) hists__fprintf_headers(&c2c_hists->hists, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) once = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) fprintf(out, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) fprintf(out, " -------------------------------------------------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) __hist_entry__snprintf(he_cl, &hpp, hpp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) fprintf(out, "%s\n", bf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) fprintf(out, " -------------------------------------------------------------\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) hists__fprintf(&c2c_hists->hists, false, 0, 0, 0, out, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) static void print_pareto(FILE *out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) struct perf_hpp_list hpp_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) struct rb_node *nd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) perf_hpp_list__init(&hpp_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) ret = hpp_list__parse(&hpp_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) "cl_num,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) "cl_rmt_hitm,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) "cl_lcl_hitm,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) "cl_stores_l1hit,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) "cl_stores_l1miss,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) "dcacheline",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) if (WARN_ONCE(ret, "failed to setup sort entries\n"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) nd = rb_first_cached(&c2c.hists.hists.entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) for (; nd; nd = rb_next(nd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (he->filtered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) print_cacheline(c2c_he->hists, he, &hpp_list, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) static void print_c2c_info(FILE *out, struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) struct evlist *evlist = session->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) bool first = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) fprintf(out, "=================================================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) fprintf(out, " c2c details \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) fprintf(out, "=================================================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) fprintf(out, "%-36s: %s\n", first ? " Events" : "", evsel__name(evsel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) first = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) fprintf(out, " Cachelines sort on : %s HITMs\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) display_str[c2c.display]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) fprintf(out, " Cacheline data grouping : %s\n", c2c.cl_sort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) static void perf_c2c__hists_fprintf(FILE *out, struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) setup_pager();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) print_c2c__display_stats(out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) fprintf(out, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) print_shared_cacheline_info(out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) fprintf(out, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) print_c2c_info(out, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) if (c2c.stats_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) fprintf(out, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) fprintf(out, "=================================================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) fprintf(out, " Shared Data Cache Line Table \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) fprintf(out, "=================================================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) fprintf(out, "#\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) hists__fprintf(&c2c.hists.hists, true, 0, 0, 0, stdout, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) fprintf(out, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) fprintf(out, "=================================================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) fprintf(out, " Shared Cache Line Distribution Pareto \n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) fprintf(out, "=================================================\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) fprintf(out, "#\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) print_pareto(out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) #ifdef HAVE_SLANG_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) static void c2c_browser__update_nr_entries(struct hist_browser *hb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) u64 nr_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) struct rb_node *nd = rb_first_cached(&hb->hists->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) while (nd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) if (!he->filtered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) nr_entries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) nd = rb_next(nd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) hb->nr_non_filtered_entries = nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) struct c2c_cacheline_browser {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) struct hist_browser hb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) struct hist_entry *he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) perf_c2c_cacheline_browser__title(struct hist_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) char *bf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) struct c2c_cacheline_browser *cl_browser;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) struct hist_entry *he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) uint64_t addr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) cl_browser = container_of(browser, struct c2c_cacheline_browser, hb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) he = cl_browser->he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) if (he->mem_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) addr = cl_address(he->mem_info->daddr.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) scnprintf(bf, size, "Cacheline 0x%lx", addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) static struct c2c_cacheline_browser*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) c2c_cacheline_browser__new(struct hists *hists, struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) struct c2c_cacheline_browser *browser;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) browser = zalloc(sizeof(*browser));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) if (browser) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) hist_browser__init(&browser->hb, hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) browser->hb.c2c_filter = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) browser->hb.title = perf_c2c_cacheline_browser__title;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) browser->he = he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) return browser;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) static int perf_c2c__browse_cacheline(struct hist_entry *he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) struct c2c_hist_entry *c2c_he;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) struct c2c_hists *c2c_hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) struct c2c_cacheline_browser *cl_browser;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) struct hist_browser *browser;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) int key = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) static const char help[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) " ENTER Toggle callchains (if present) \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) " n Toggle Node details info \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) " s Toggle full length of symbol and source line columns \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) " q Return back to cacheline list \n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) if (!he)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) /* Display compact version first. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) c2c.symbol_full = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) c2c_he = container_of(he, struct c2c_hist_entry, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) c2c_hists = c2c_he->hists;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) cl_browser = c2c_cacheline_browser__new(&c2c_hists->hists, he);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) if (cl_browser == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) browser = &cl_browser->hb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) /* reset abort key so that it can get Ctrl-C as a key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) SLang_reset_tty();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) SLang_init_tty(0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) c2c_browser__update_nr_entries(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) key = hist_browser__run(browser, "? - help", true, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) switch (key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) case 's':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) c2c.symbol_full = !c2c.symbol_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) case 'n':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) c2c.node_info = (c2c.node_info + 1) % 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) setup_nodes_header();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) case 'q':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) ui_browser__help_window(&browser->b, help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) free(cl_browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) static int perf_c2c_browser__title(struct hist_browser *browser,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) char *bf, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) scnprintf(bf, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) "Shared Data Cache Line Table "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) "(%lu entries, sorted on %s HITMs)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) browser->nr_non_filtered_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) display_str[c2c.display]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) static struct hist_browser*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) perf_c2c_browser__new(struct hists *hists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) struct hist_browser *browser = hist_browser__new(hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) if (browser) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) browser->title = perf_c2c_browser__title;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) browser->c2c_filter = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) return browser;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) static int perf_c2c__hists_browse(struct hists *hists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) struct hist_browser *browser;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) int key = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) static const char help[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) " d Display cacheline details \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) " ENTER Toggle callchains (if present) \n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) " q Quit \n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) browser = perf_c2c_browser__new(hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) if (browser == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) /* reset abort key so that it can get Ctrl-C as a key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) SLang_reset_tty();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) SLang_init_tty(0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) c2c_browser__update_nr_entries(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) key = hist_browser__run(browser, "? - help", true, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) switch (key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) case 'q':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) case 'd':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) perf_c2c__browse_cacheline(browser->he_selection);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) case '?':
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) ui_browser__help_window(&browser->b, help);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) hist_browser__delete(browser);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) static void perf_c2c_display(struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) if (use_browser == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) perf_c2c__hists_fprintf(stdout, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) perf_c2c__hists_browse(&c2c.hists.hists);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) static void perf_c2c_display(struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) use_browser = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) perf_c2c__hists_fprintf(stdout, session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) #endif /* HAVE_SLANG_SUPPORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) static char *fill_line(const char *orig, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) int i, j, olen = strlen(orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) buf = zalloc(len + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) j = len / 2 - olen / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) for (i = 0; i < j - 1; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) buf[i] = '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) buf[i++] = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) strcpy(buf + i, orig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) i += olen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) buf[i++] = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) for (; i < len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) buf[i] = '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) static int ui_quirks(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) const char *nodestr = "Data address";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) if (!c2c.use_stdio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) dim_offset.width = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) dim_offset.header = header_offset_tui;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) nodestr = "CL";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) dim_percent_hitm.header = percent_hitm_header[c2c.display];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) /* Fix the zero line for dcacheline column. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) buf = fill_line("Cacheline", dim_dcacheline.width +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) dim_dcacheline_node.width +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) dim_dcacheline_count.width + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) dim_dcacheline.header.line[0].text = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) /* Fix the zero line for offset column. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) buf = fill_line(nodestr, dim_offset.width +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) dim_offset_node.width +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) dim_dcacheline_count.width + 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) dim_offset.header.line[0].text = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) #define CALLCHAIN_DEFAULT_OPT "graph,0.5,caller,function,percent"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) const char callchain_help[] = "Display call graph (stack chain/backtrace):\n\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) CALLCHAIN_REPORT_HELP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) "\n\t\t\t\tDefault: " CALLCHAIN_DEFAULT_OPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) parse_callchain_opt(const struct option *opt, const char *arg, int unset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) struct callchain_param *callchain = opt->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) callchain->enabled = !unset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) * --no-call-graph
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) if (unset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) symbol_conf.use_callchain = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) callchain->mode = CHAIN_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) return parse_callchain_report_opt(arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) static int setup_callchain(struct evlist *evlist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) u64 sample_type = evlist__combined_sample_type(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) enum perf_call_graph_mode mode = CALLCHAIN_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) if ((sample_type & PERF_SAMPLE_REGS_USER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) (sample_type & PERF_SAMPLE_STACK_USER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) mode = CALLCHAIN_DWARF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) dwarf_callchain_users = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) } else if (sample_type & PERF_SAMPLE_BRANCH_STACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) mode = CALLCHAIN_LBR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) else if (sample_type & PERF_SAMPLE_CALLCHAIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) mode = CALLCHAIN_FP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) if (!callchain_param.enabled &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) callchain_param.mode != CHAIN_NONE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) mode != CALLCHAIN_NONE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) symbol_conf.use_callchain = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) if (callchain_register_param(&callchain_param) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) ui__error("Can't register callchain params.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) if (c2c.stitch_lbr && (mode != CALLCHAIN_LBR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) ui__warning("Can't find LBR callchain. Switch off --stitch-lbr.\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) "Please apply --call-graph lbr when recording.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) c2c.stitch_lbr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) callchain_param.record_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) callchain_param.min_percent = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) static int setup_display(const char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) const char *display = str ?: "tot";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) if (!strcmp(display, "tot"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) c2c.display = DISPLAY_TOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) else if (!strcmp(display, "rmt"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) c2c.display = DISPLAY_RMT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) else if (!strcmp(display, "lcl"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) c2c.display = DISPLAY_LCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) pr_err("failed: unknown display type: %s\n", str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) #define for_each_token(__tok, __buf, __sep, __tmp) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) for (__tok = strtok_r(__buf, __sep, &__tmp); __tok; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) __tok = strtok_r(NULL, __sep, &__tmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) static int build_cl_output(char *cl_sort, bool no_source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) char *tok, *tmp, *buf = strdup(cl_sort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) bool add_pid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) bool add_tid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) bool add_iaddr = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) bool add_sym = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) bool add_dso = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) bool add_src = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) for_each_token(tok, buf, ",", tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) if (!strcmp(tok, "tid")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) add_tid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) } else if (!strcmp(tok, "pid")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) add_pid = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) } else if (!strcmp(tok, "iaddr")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) add_iaddr = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) add_sym = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) add_dso = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) add_src = no_source ? false : true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) } else if (!strcmp(tok, "dso")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) add_dso = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) } else if (strcmp(tok, "offset")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) pr_err("unrecognized sort token: %s\n", tok);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) if (asprintf(&c2c.cl_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) "%s%s%s%s%s%s%s%s%s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) c2c.use_stdio ? "cl_num_empty," : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) "percent_rmt_hitm,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) "percent_lcl_hitm,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) "percent_stores_l1hit,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) "percent_stores_l1miss,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) "offset,offset_node,dcacheline_count,",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) add_pid ? "pid," : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) add_tid ? "tid," : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) add_iaddr ? "iaddr," : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) "mean_rmt,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) "mean_lcl,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) "mean_load,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) "tot_recs,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) "cpucnt,",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) add_sym ? "symbol," : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) add_dso ? "dso," : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) add_src ? "cl_srcline," : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) "node") < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) c2c.show_src = add_src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) free(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) static int setup_coalesce(const char *coalesce, bool no_source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) const char *c = coalesce ?: coalesce_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) if (asprintf(&c2c.cl_sort, "offset,%s", c) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) if (build_cl_output(c2c.cl_sort, no_source))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) if (asprintf(&c2c.cl_resort, "offset,%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) c2c.display == DISPLAY_TOT ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) "tot_hitm" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) c2c.display == DISPLAY_RMT ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) "rmt_hitm,lcl_hitm" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) "lcl_hitm,rmt_hitm") < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) pr_debug("coalesce sort fields: %s\n", c2c.cl_sort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) pr_debug("coalesce resort fields: %s\n", c2c.cl_resort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) pr_debug("coalesce output fields: %s\n", c2c.cl_output);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) static int perf_c2c__report(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) struct perf_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) struct ui_progress prog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) struct perf_data data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) .mode = PERF_DATA_MODE_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) char callchain_default_opt[] = CALLCHAIN_DEFAULT_OPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) const char *display = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) const char *coalesce = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) bool no_source = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) const struct option options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) "file", "vmlinux pathname"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) OPT_STRING('i', "input", &input_name, "file",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) "the input file to process"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) OPT_INCR('N', "node-info", &c2c.node_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) "show extra node info in report (repeat for more info)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) #ifdef HAVE_SLANG_SUPPORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) OPT_BOOLEAN(0, "stdio", &c2c.use_stdio, "Use the stdio interface"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) OPT_BOOLEAN(0, "stats", &c2c.stats_only,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) "Display only statistic tables (implies --stdio)"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) OPT_BOOLEAN(0, "full-symbols", &c2c.symbol_full,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) "Display full length of symbols"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) OPT_BOOLEAN(0, "no-source", &no_source,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) "Do not display Source Line column"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) OPT_BOOLEAN(0, "show-all", &c2c.show_all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) "Show all captured HITM lines."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) OPT_CALLBACK_DEFAULT('g', "call-graph", &callchain_param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) "print_type,threshold[,print_limit],order,sort_key[,branch],value",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) callchain_help, &parse_callchain_opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) callchain_default_opt),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) OPT_STRING('d', "display", &display, "Switch HITM output type", "lcl,rmt"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) OPT_STRING('c', "coalesce", &coalesce, "coalesce fields",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) "coalesce fields: pid,tid,iaddr,dso"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) OPT_BOOLEAN(0, "stitch-lbr", &c2c.stitch_lbr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) "Enable LBR callgraph stitching approach"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) OPT_PARENT(c2c_options),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) argc = parse_options(argc, argv, options, report_c2c_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) PARSE_OPT_STOP_AT_NON_OPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) if (argc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) usage_with_options(report_c2c_usage, options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) if (c2c.stats_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) c2c.use_stdio = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) if (!input_name || !strlen(input_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) input_name = "perf.data";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) data.path = input_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) data.force = symbol_conf.force;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) err = setup_display(display);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) err = setup_coalesce(coalesce, no_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) pr_debug("Failed to initialize hists\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) err = c2c_hists__init(&c2c.hists, "dcacheline", 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) pr_debug("Failed to initialize hists\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) session = perf_session__new(&data, 0, &c2c.tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) if (IS_ERR(session)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) err = PTR_ERR(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) pr_debug("Error creating perf session\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) err = setup_nodes(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) pr_err("Failed setup nodes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) err = mem2node__init(&c2c.mem2node, &session->header.env);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) goto out_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) err = setup_callchain(session->evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) goto out_mem2node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) if (symbol__init(&session->header.env) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) goto out_mem2node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) /* No pipe support at the moment. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) if (perf_data__is_pipe(session->data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) pr_debug("No pipe support at the moment.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) goto out_mem2node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) if (c2c.use_stdio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) use_browser = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) use_browser = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) setup_browser(false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) err = perf_session__process_events(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) pr_err("failed to process sample\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) goto out_mem2node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) c2c_hists__reinit(&c2c.hists,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) "cl_idx,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) "dcacheline,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) "dcacheline_node,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) "dcacheline_count,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) "percent_hitm,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) "tot_hitm,lcl_hitm,rmt_hitm,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) "tot_recs,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) "tot_loads,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) "tot_stores,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) "stores_l1hit,stores_l1miss,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) "ld_fbhit,ld_l1hit,ld_l2hit,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) "ld_lclhit,lcl_hitm,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) "ld_rmthit,rmt_hitm,"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) "dram_lcl,dram_rmt",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) c2c.display == DISPLAY_TOT ? "tot_hitm" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) c2c.display == DISPLAY_LCL ? "lcl_hitm" : "rmt_hitm"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) ui_progress__init(&prog, c2c.hists.hists.nr_entries, "Sorting...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) hists__collapse_resort(&c2c.hists.hists, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) hists__output_resort_cb(&c2c.hists.hists, &prog, resort_hitm_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) hists__iterate_cb(&c2c.hists.hists, resort_cl_cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) ui_progress__finish();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) if (ui_quirks()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) pr_err("failed to setup UI\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) goto out_mem2node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) perf_c2c_display(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) out_mem2node:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) mem2node__exit(&c2c.mem2node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) out_session:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) perf_session__delete(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) static int parse_record_events(const struct option *opt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) const char *str, int unset __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) bool *event_set = (bool *) opt->value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) if (!strcmp(str, "list")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) perf_mem_events__list();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) if (perf_mem_events__parse(str))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) exit(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) *event_set = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) static const char * const __usage_record[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) "perf c2c record [<options>] [<command>]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) "perf c2c record [<options>] -- <command> [<options>]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) static const char * const *record_mem_usage = __usage_record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) static int perf_c2c__record(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) int rec_argc, i = 0, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) const char **rec_argv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) bool all_user = false, all_kernel = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) bool event_set = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) struct option options[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) OPT_CALLBACK('e', "event", &event_set, "event",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) "event selector. Use 'perf c2c record -e list' to list available events",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) parse_record_events),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) OPT_BOOLEAN('u', "all-user", &all_user, "collect only user level data"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) OPT_BOOLEAN('k', "all-kernel", &all_kernel, "collect only kernel level data"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) OPT_UINTEGER('l', "ldlat", &perf_mem_events__loads_ldlat, "setup mem-loads latency"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) OPT_PARENT(c2c_options),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) OPT_END()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) if (perf_mem_events__init()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) pr_err("failed: memory events not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) argc = parse_options(argc, argv, options, record_mem_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) PARSE_OPT_KEEP_UNKNOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) rec_argc = argc + 11; /* max number of arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) rec_argv = calloc(rec_argc + 1, sizeof(char *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) if (!rec_argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) rec_argv[i++] = "record";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) if (!event_set) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) perf_mem_events[PERF_MEM_EVENTS__LOAD].record = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) perf_mem_events[PERF_MEM_EVENTS__STORE].record = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) if (perf_mem_events[PERF_MEM_EVENTS__LOAD].record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) rec_argv[i++] = "-W";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) rec_argv[i++] = "-d";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) rec_argv[i++] = "--phys-data";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) rec_argv[i++] = "--sample-cpu";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) for (j = 0; j < PERF_MEM_EVENTS__MAX; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) if (!perf_mem_events[j].record)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) if (!perf_mem_events[j].supported) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) pr_err("failed: event '%s' not supported\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) perf_mem_events[j].name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) free(rec_argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) rec_argv[i++] = "-e";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) rec_argv[i++] = perf_mem_events__name(j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) if (all_user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) rec_argv[i++] = "--all-user";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) if (all_kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) rec_argv[i++] = "--all-kernel";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) for (j = 0; j < argc; j++, i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) rec_argv[i] = argv[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) if (verbose > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) pr_debug("calling: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) while (rec_argv[j]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) pr_debug("%s ", rec_argv[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) j++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) pr_debug("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) ret = cmd_record(i, rec_argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) free(rec_argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) int cmd_c2c(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) argc = parse_options(argc, argv, c2c_options, c2c_usage,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) PARSE_OPT_STOP_AT_NON_OPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) if (!argc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) usage_with_options(c2c_usage, c2c_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) if (!strncmp(argv[0], "rec", 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) return perf_c2c__record(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) } else if (!strncmp(argv[0], "rep", 3)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) return perf_c2c__report(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) usage_with_options(c2c_usage, c2c_options);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) }