perf tools: Add mem access sampling core support
[linux-3.10.git] / tools / perf / util / hist.c
index 97ddd18..99cc719 100644 (file)
@@ -67,12 +67,16 @@ static void hists__set_unres_dso_col_len(struct hists *hists, int dso)
 void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
 {
        const unsigned int unresolved_col_width = BITS_PER_LONG / 4;
+       int symlen;
        u16 len;
 
        if (h->ms.sym)
                hists__new_col_len(hists, HISTC_SYMBOL, h->ms.sym->namelen + 4);
-       else
+       else {
+               symlen = unresolved_col_width + 4 + 2;
+               hists__new_col_len(hists, HISTC_SYMBOL, symlen);
                hists__set_unres_dso_col_len(hists, HISTC_DSO);
+       }
 
        len = thread__comm_len(h->thread);
        if (hists__new_col_len(hists, HISTC_COMM, len))
@@ -87,7 +91,6 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
                hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen);
 
        if (h->branch_info) {
-               int symlen;
                /*
                 * +4 accounts for '[x] ' priv level info
                 * +2 account of 0x prefix on raw addresses
@@ -116,6 +119,42 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
                        hists__set_unres_dso_col_len(hists, HISTC_DSO_TO);
                }
        }
+
+       if (h->mem_info) {
+               /*
+                * +4 accounts for '[x] ' priv level info
+                * +2 account of 0x prefix on raw addresses
+                */
+               if (h->mem_info->daddr.sym) {
+                       symlen = (int)h->mem_info->daddr.sym->namelen + 4
+                              + unresolved_col_width + 2;
+                       hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
+                                          symlen);
+               } else {
+                       symlen = unresolved_col_width + 4 + 2;
+                       hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL,
+                                          symlen);
+               }
+               if (h->mem_info->daddr.map) {
+                       symlen = dso__name_len(h->mem_info->daddr.map->dso);
+                       hists__new_col_len(hists, HISTC_MEM_DADDR_DSO,
+                                          symlen);
+               } else {
+                       symlen = unresolved_col_width + 4 + 2;
+                       hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
+               }
+       } else {
+               symlen = unresolved_col_width + 4 + 2;
+               hists__new_col_len(hists, HISTC_MEM_DADDR_SYMBOL, symlen);
+               hists__set_unres_dso_col_len(hists, HISTC_MEM_DADDR_DSO);
+       }
+
+       hists__new_col_len(hists, HISTC_MEM_LOCKED, 6);
+       hists__new_col_len(hists, HISTC_MEM_TLB, 22);
+       hists__new_col_len(hists, HISTC_MEM_SNOOP, 12);
+       hists__new_col_len(hists, HISTC_MEM_LVL, 21 + 3);
+       hists__new_col_len(hists, HISTC_LOCAL_WEIGHT, 12);
+       hists__new_col_len(hists, HISTC_GLOBAL_WEIGHT, 12);
 }
 
 void hists__output_recalc_col_len(struct hists *hists, int max_rows)
@@ -158,6 +197,7 @@ static void hist_entry__add_cpumode_period(struct hist_entry *he,
 static void he_stat__add_period(struct he_stat *he_stat, u64 period,
                                u64 weight)
 {
+
        he_stat->period         += period;
        he_stat->weight         += weight;
        he_stat->nr_events      += 1;
@@ -243,7 +283,7 @@ void hists__decay_entries_threaded(struct hists *hists,
 static struct hist_entry *hist_entry__new(struct hist_entry *template)
 {
        size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_root) : 0;
-       struct hist_entry *he = malloc(sizeof(*he) + callchain_size);
+       struct hist_entry *he = zalloc(sizeof(*he) + callchain_size);
 
        if (he != NULL) {
                *he = *template;
@@ -258,6 +298,13 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
                                he->branch_info->to.map->referenced = true;
                }
 
+               if (he->mem_info) {
+                       if (he->mem_info->iaddr.map)
+                               he->mem_info->iaddr.map->referenced = true;
+                       if (he->mem_info->daddr.map)
+                               he->mem_info->daddr.map->referenced = true;
+               }
+
                if (symbol_conf.use_callchain)
                        callchain_init(he->callchain);
 
@@ -346,6 +393,36 @@ out_unlock:
        return he;
 }
 
+struct hist_entry *__hists__add_mem_entry(struct hists *self,
+                                         struct addr_location *al,
+                                         struct symbol *sym_parent,
+                                         struct mem_info *mi,
+                                         u64 period,
+                                         u64 weight)
+{
+       struct hist_entry entry = {
+               .thread = al->thread,
+               .ms = {
+                       .map    = al->map,
+                       .sym    = al->sym,
+               },
+               .stat = {
+                       .period = period,
+                       .weight = weight,
+                       .nr_events = 1,
+               },
+               .cpu    = al->cpu,
+               .ip     = al->addr,
+               .level  = al->level,
+               .parent = sym_parent,
+               .filtered = symbol__parent_filter(sym_parent),
+               .hists = self,
+               .mem_info = mi,
+               .branch_info = NULL,
+       };
+       return add_hist_entry(self, &entry, al, period, weight);
+}
+
 struct hist_entry *__hists__add_branch_entry(struct hists *self,
                                             struct addr_location *al,
                                             struct symbol *sym_parent,
@@ -371,6 +448,7 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
                .filtered = symbol__parent_filter(sym_parent),
                .branch_info = bi,
                .hists  = self,
+               .mem_info = NULL,
        };
 
        return add_hist_entry(self, &entry, al, period, weight);
@@ -398,6 +476,8 @@ struct hist_entry *__hists__add_entry(struct hists *self,
                .parent = sym_parent,
                .filtered = symbol__parent_filter(sym_parent),
                .hists  = self,
+               .branch_info = NULL,
+               .mem_info = NULL,
        };
 
        return add_hist_entry(self, &entry, al, period, weight);