Em Fri, Feb 22, 2013 at 03:28:38PM +0100, Stephane Eranian escreveu: > > When the memory sampling sort orders were used on perf.data > files without memory sampling data, it would crash perf. This > patch fixes this by handling the lack of memory information > gracefully, printing N/A and formatting columns correctly > whenever necessary. > > This patch is to be applied on top of the memory sampling > patchset. It is relative to Arnaldo's perf/mem branch.
Ok, folded that into the original patch, so that we can bisect things in this area. Updating the perf/mem branch with this, i.e. force pushed. - Arnaldo > Reported-by: Arnaldo Carvalho de Melo <[email protected]> > Signed-off-by: Stephane Eranian <[email protected]> > --- > > diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h > index 4008b7f..98572ca 100644 > --- a/tools/perf/util/event.h > +++ b/tools/perf/util/event.h > @@ -99,6 +99,13 @@ struct perf_sample { > struct stack_dump user_stack; > }; > > +#define PERF_MEM_DATA_SRC_NONE \ > + (PERF_MEM_S(OP, NA) |\ > + PERF_MEM_S(LVL, NA) |\ > + PERF_MEM_S(SNOOP, NA) |\ > + PERF_MEM_S(LOCK, NA) |\ > + PERF_MEM_S(TLB, NA)) > + > struct build_id_event { > struct perf_event_header header; > pid_t pid; > diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c > index bace0cc..d1799a4 100644 > --- a/tools/perf/util/evsel.c > +++ b/tools/perf/util/evsel.c > @@ -1175,7 +1175,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, > union perf_event *event, > array++; > } > > - data->dsrc = 0; > + data->dsrc = PERF_MEM_DATA_SRC_NONE; > if (type & PERF_SAMPLE_DATA_SRC) { > data->dsrc = *array; > array++; > diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c > index 043593d..454d7f1 100644 > --- a/tools/perf/util/hist.c > +++ b/tools/perf/util/hist.c > @@ -118,7 +118,9 @@ void hists__calc_col_len(struct hists *hists, struct > hist_entry *h) > hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); > hists__set_unres_dso_col_len(hists, HISTC_DSO_TO); > } > - } else if (h->mem_info) { > + } > + > + if (h->mem_info) { > /* > * +4 accounts for '[x] ' priv level info > * +2 account of 0x prefix on raw addresses > @@ -141,11 +143,15 @@ void hists__calc_col_len(struct hists *hists, struct > hist_entry *h) > symlen = unresolved_col_width + 4 + 2; > 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); > + } 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); > > } > > diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c > index 1dc3860..0fdaac7 100644 > --- a/tools/perf/util/sort.c > +++ b/tools/perf/util/sort.c > @@ -198,7 +198,7 @@ static int _hist_entry__sym_snprintf(struct map *map, > struct symbol *sym, > } > > ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level); > - if (sym) { > + if (sym && map) { > if (map->type == MAP__VARIABLE) { > ret += repsep_snprintf(bf + ret, size - ret, "%s", > sym->name); > ret += repsep_snprintf(bf + ret, size - ret, "+0x%llx", > @@ -469,39 +469,72 @@ static int hist_entry__mispredict_snprintf(struct > hist_entry *self, char *bf, > static int64_t > sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right) > { > - struct addr_map_symbol *l = &left->mem_info->daddr; > - struct addr_map_symbol *r = &right->mem_info->daddr; > + uint64_t l = 0, r = 0; > > - return (int64_t)(r->addr - l->addr); > + if (left->mem_info) > + l = left->mem_info->daddr.addr; > + if (right->mem_info) > + r = right->mem_info->daddr.addr; > + > + return (int64_t)(r - l); > } > > static int hist_entry__daddr_snprintf(struct hist_entry *self, char *bf, > size_t size, unsigned int width) > { > - return _hist_entry__sym_snprintf(self->mem_info->daddr.map, > - self->mem_info->daddr.sym, > - self->mem_info->daddr.addr, > - self->level, bf, size, width); > + uint64_t addr = 0; > + struct map *map = NULL; > + struct symbol *sym = NULL; > + > + if (self->mem_info) { > + addr = self->mem_info->daddr.addr; > + map = self->mem_info->daddr.map; > + sym = self->mem_info->daddr.sym; > + } > + return _hist_entry__sym_snprintf(map, sym, addr, self->level, bf, size, > + width); > } > > static int64_t > sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right) > { > - return _sort__dso_cmp(left->mem_info->daddr.map, > right->mem_info->daddr.map); > + struct map *map_l = NULL; > + struct map *map_r = NULL; > + > + if (left->mem_info) > + map_l = left->mem_info->daddr.map; > + if (right->mem_info) > + map_r = right->mem_info->daddr.map; > + > + return _sort__dso_cmp(map_l, map_r); > } > > static int hist_entry__dso_daddr_snprintf(struct hist_entry *self, char *bf, > size_t size, unsigned int width) > { > - return _hist_entry__dso_snprintf(self->mem_info->daddr.map, bf, size, > - width); > + struct map *map = NULL; > + > + if (self->mem_info) > + map = self->mem_info->daddr.map; > + > + return _hist_entry__dso_snprintf(map, bf, size, width); > } > > static int64_t > sort__locked_cmp(struct hist_entry *left, struct hist_entry *right) > { > - union perf_mem_data_src dsrc_l = left->mem_info->dsrc; > - union perf_mem_data_src dsrc_r = right->mem_info->dsrc; > + union perf_mem_data_src dsrc_l; > + union perf_mem_data_src dsrc_r; > + > + if (left->mem_info) > + dsrc_l = left->mem_info->dsrc; > + else > + dsrc_l.mem_lock = PERF_MEM_LOCK_NA; > + > + if (right->mem_info) > + dsrc_r = right->mem_info->dsrc; > + else > + dsrc_r.mem_lock = PERF_MEM_LOCK_NA; > > return (int64_t)(dsrc_r.mem_lock - dsrc_l.mem_lock); > } > @@ -509,8 +542,11 @@ sort__locked_cmp(struct hist_entry *left, struct > hist_entry *right) > static int hist_entry__locked_snprintf(struct hist_entry *self, char *bf, > size_t size, unsigned int width) > { > - const char *out = "??"; > - u64 mask = self->mem_info->dsrc.mem_lock; > + const char *out; > + u64 mask = PERF_MEM_LOCK_NA; > + > + if (self->mem_info) > + mask = self->mem_info->dsrc.mem_lock; > > if (mask & PERF_MEM_LOCK_NA) > out = "N/A"; > @@ -525,8 +561,18 @@ static int hist_entry__locked_snprintf(struct hist_entry > *self, char *bf, > static int64_t > sort__tlb_cmp(struct hist_entry *left, struct hist_entry *right) > { > - union perf_mem_data_src dsrc_l = left->mem_info->dsrc; > - union perf_mem_data_src dsrc_r = right->mem_info->dsrc; > + union perf_mem_data_src dsrc_l; > + union perf_mem_data_src dsrc_r; > + > + if (left->mem_info) > + dsrc_l = left->mem_info->dsrc; > + else > + dsrc_l.mem_dtlb = PERF_MEM_TLB_NA; > + > + if (right->mem_info) > + dsrc_r = right->mem_info->dsrc; > + else > + dsrc_r.mem_dtlb = PERF_MEM_TLB_NA; > > return (int64_t)(dsrc_r.mem_dtlb - dsrc_l.mem_dtlb); > } > @@ -548,11 +594,14 @@ static int hist_entry__tlb_snprintf(struct hist_entry > *self, char *bf, > char out[64]; > size_t sz = sizeof(out) - 1; /* -1 for null termination */ > size_t l = 0, i; > - u64 m = self->mem_info->dsrc.mem_dtlb; > + u64 m = PERF_MEM_TLB_NA; > u64 hit, miss; > > out[0] = '\0'; > > + if (self->mem_info) > + m = self->mem_info->dsrc.mem_dtlb; > + > hit = m & PERF_MEM_TLB_HIT; > miss = m & PERF_MEM_TLB_MISS; > > @@ -569,6 +618,8 @@ static int hist_entry__tlb_snprintf(struct hist_entry > *self, char *bf, > strncat(out, tlb_access[i], sz - l); > l += strlen(tlb_access[i]); > } > + if (*out == '\0') > + strcpy(out, "N/A"); > if (hit) > strncat(out, " hit", sz - l); > if (miss) > @@ -580,8 +631,18 @@ static int hist_entry__tlb_snprintf(struct hist_entry > *self, char *bf, > static int64_t > sort__lvl_cmp(struct hist_entry *left, struct hist_entry *right) > { > - union perf_mem_data_src dsrc_l = left->mem_info->dsrc; > - union perf_mem_data_src dsrc_r = right->mem_info->dsrc; > + union perf_mem_data_src dsrc_l; > + union perf_mem_data_src dsrc_r; > + > + if (left->mem_info) > + dsrc_l = left->mem_info->dsrc; > + else > + dsrc_l.mem_lvl = PERF_MEM_LVL_NA; > + > + if (right->mem_info) > + dsrc_r = right->mem_info->dsrc; > + else > + dsrc_r.mem_lvl = PERF_MEM_LVL_NA; > > return (int64_t)(dsrc_r.mem_lvl - dsrc_l.mem_lvl); > } > @@ -610,9 +671,12 @@ static int hist_entry__lvl_snprintf(struct hist_entry > *self, char *bf, > char out[64]; > size_t sz = sizeof(out) - 1; /* -1 for null termination */ > size_t i, l = 0; > - u64 m = self->mem_info->dsrc.mem_lvl; > + u64 m = PERF_MEM_LVL_NA; > u64 hit, miss; > > + if (self->mem_info) > + m = self->mem_info->dsrc.mem_lvl; > + > out[0] = '\0'; > > hit = m & PERF_MEM_LVL_HIT; > @@ -631,6 +695,8 @@ static int hist_entry__lvl_snprintf(struct hist_entry > *self, char *bf, > strncat(out, mem_lvl[i], sz - l); > l += strlen(mem_lvl[i]); > } > + if (*out == '\0') > + strcpy(out, "N/A"); > if (hit) > strncat(out, " hit", sz - l); > if (miss) > @@ -642,8 +708,18 @@ static int hist_entry__lvl_snprintf(struct hist_entry > *self, char *bf, > static int64_t > sort__snoop_cmp(struct hist_entry *left, struct hist_entry *right) > { > - union perf_mem_data_src dsrc_l = left->mem_info->dsrc; > - union perf_mem_data_src dsrc_r = right->mem_info->dsrc; > + union perf_mem_data_src dsrc_l; > + union perf_mem_data_src dsrc_r; > + > + if (left->mem_info) > + dsrc_l = left->mem_info->dsrc; > + else > + dsrc_l.mem_snoop = PERF_MEM_SNOOP_NA; > + > + if (right->mem_info) > + dsrc_r = right->mem_info->dsrc; > + else > + dsrc_r.mem_snoop = PERF_MEM_SNOOP_NA; > > return (int64_t)(dsrc_r.mem_snoop - dsrc_l.mem_snoop); > } > @@ -663,10 +739,13 @@ static int hist_entry__snoop_snprintf(struct hist_entry > *self, char *bf, > char out[64]; > size_t sz = sizeof(out) - 1; /* -1 for null termination */ > size_t i, l = 0; > - u64 m = self->mem_info->dsrc.mem_snoop; > + u64 m = PERF_MEM_SNOOP_NA; > > out[0] = '\0'; > > + if (self->mem_info) > + m = self->mem_info->dsrc.mem_snoop; > + > for (i = 0; m && i < NUM_SNOOP_ACCESS; i++, m >>= 1) { > if (!(m & 0x1)) > continue; > @@ -678,6 +757,9 @@ static int hist_entry__snoop_snprintf(struct hist_entry > *self, char *bf, > l += strlen(snoop_access[i]); > } > > + if (*out == '\0') > + strcpy(out, "N/A"); > + > return repsep_snprintf(bf, size, "%-*s", width, out); > } > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/

