summaryrefslogtreecommitdiffstats
path: root/tools/perf/util
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util')
-rw-r--r--tools/perf/util/event.h1
-rw-r--r--tools/perf/util/evsel.c10
-rw-r--r--tools/perf/util/hist.c23
-rw-r--r--tools/perf/util/hist.h8
-rw-r--r--tools/perf/util/session.c3
-rw-r--r--tools/perf/util/sort.c45
-rw-r--r--tools/perf/util/sort.h3
7 files changed, 84 insertions, 9 deletions
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
index 0d573ff4771..a97fbbe6b3b 100644
--- a/tools/perf/util/event.h
+++ b/tools/perf/util/event.h
@@ -88,6 +88,7 @@ struct perf_sample {
u64 id;
u64 stream_id;
u64 period;
+ u64 weight;
u32 cpu;
u32 raw_size;
void *raw_data;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 1adb824610f..23061a6ccd7 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -563,6 +563,9 @@ void perf_evsel__config(struct perf_evsel *evsel,
attr->branch_sample_type = opts->branch_stack;
}
+ if (opts->sample_weight)
+ attr->sample_type |= PERF_SAMPLE_WEIGHT;
+
attr->mmap = track;
attr->comm = track;
@@ -1017,6 +1020,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
data->cpu = data->pid = data->tid = -1;
data->stream_id = data->id = data->time = -1ULL;
data->period = 1;
+ data->weight = 0;
if (event->header.type != PERF_RECORD_SAMPLE) {
if (!evsel->attr.sample_id_all)
@@ -1167,6 +1171,12 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
}
}
+ data->weight = 0;
+ if (type & PERF_SAMPLE_WEIGHT) {
+ data->weight = *array;
+ array++;
+ }
+
return 0;
}
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index f855941bebe..97ddd18acd7 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -155,9 +155,11 @@ static void hist_entry__add_cpumode_period(struct hist_entry *he,
}
}
-static void he_stat__add_period(struct he_stat *he_stat, u64 period)
+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;
}
@@ -169,12 +171,14 @@ static void he_stat__add_stat(struct he_stat *dest, struct he_stat *src)
dest->period_guest_sys += src->period_guest_sys;
dest->period_guest_us += src->period_guest_us;
dest->nr_events += src->nr_events;
+ dest->weight += src->weight;
}
static void hist_entry__decay(struct hist_entry *he)
{
he->stat.period = (he->stat.period * 7) / 8;
he->stat.nr_events = (he->stat.nr_events * 7) / 8;
+ /* XXX need decay for weight too? */
}
static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
@@ -282,7 +286,8 @@ static u8 symbol__parent_filter(const struct symbol *parent)
static struct hist_entry *add_hist_entry(struct hists *hists,
struct hist_entry *entry,
struct addr_location *al,
- u64 period)
+ u64 period,
+ u64 weight)
{
struct rb_node **p;
struct rb_node *parent = NULL;
@@ -306,7 +311,7 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
cmp = hist_entry__cmp(he, entry);
if (!cmp) {
- he_stat__add_period(&he->stat, period);
+ he_stat__add_period(&he->stat, period, weight);
/* If the map of an existing hist_entry has
* become out-of-date due to an exec() or
@@ -345,7 +350,8 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
struct addr_location *al,
struct symbol *sym_parent,
struct branch_info *bi,
- u64 period)
+ u64 period,
+ u64 weight)
{
struct hist_entry entry = {
.thread = al->thread,
@@ -359,6 +365,7 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
.stat = {
.period = period,
.nr_events = 1,
+ .weight = weight,
},
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
@@ -366,12 +373,13 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
.hists = self,
};
- return add_hist_entry(self, &entry, al, period);
+ return add_hist_entry(self, &entry, al, period, weight);
}
struct hist_entry *__hists__add_entry(struct hists *self,
struct addr_location *al,
- struct symbol *sym_parent, u64 period)
+ struct symbol *sym_parent, u64 period,
+ u64 weight)
{
struct hist_entry entry = {
.thread = al->thread,
@@ -385,13 +393,14 @@ struct hist_entry *__hists__add_entry(struct hists *self,
.stat = {
.period = period,
.nr_events = 1,
+ .weight = weight,
},
.parent = sym_parent,
.filtered = symbol__parent_filter(sym_parent),
.hists = self,
};
- return add_hist_entry(self, &entry, al, period);
+ return add_hist_entry(self, &entry, al, period, weight);
}
int64_t
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 848331377bd..121cc14b604 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -49,6 +49,8 @@ enum hist_column {
HISTC_DSO_FROM,
HISTC_DSO_TO,
HISTC_SRCLINE,
+ HISTC_LOCAL_WEIGHT,
+ HISTC_GLOBAL_WEIGHT,
HISTC_NR_COLS, /* Last entry */
};
@@ -73,7 +75,8 @@ struct hists {
struct hist_entry *__hists__add_entry(struct hists *self,
struct addr_location *al,
- struct symbol *parent, u64 period);
+ struct symbol *parent, u64 period,
+ u64 weight);
int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
int hist_entry__sort_snprintf(struct hist_entry *self, char *bf, size_t size,
@@ -84,7 +87,8 @@ struct hist_entry *__hists__add_branch_entry(struct hists *self,
struct addr_location *al,
struct symbol *sym_parent,
struct branch_info *bi,
- u64 period);
+ u64 period,
+ u64 weight);
void hists__output_resort(struct hists *self);
void hists__output_resort_threaded(struct hists *hists);
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index c8ba120b0db..627be09b479 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -798,6 +798,9 @@ static void dump_sample(struct perf_evsel *evsel, union perf_event *event,
if (sample_type & PERF_SAMPLE_STACK_USER)
stack_user__printf(&sample->user_stack);
+
+ if (sample_type & PERF_SAMPLE_WEIGHT)
+ printf("... weight: %" PRIu64 "\n", sample->weight);
}
static struct machine *
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index d41926cb9e3..d66bcd33248 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -464,6 +464,49 @@ struct sort_entry sort_mispredict = {
.se_width_idx = HISTC_MISPREDICT,
};
+static u64 he_weight(struct hist_entry *he)
+{
+ return he->stat.nr_events ? he->stat.weight / he->stat.nr_events : 0;
+}
+
+static int64_t
+sort__local_weight_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+ return he_weight(left) - he_weight(right);
+}
+
+static int hist_entry__local_weight_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width)
+{
+ return repsep_snprintf(bf, size, "%-*llu", width, he_weight(self));
+}
+
+struct sort_entry sort_local_weight = {
+ .se_header = "Local Weight",
+ .se_cmp = sort__local_weight_cmp,
+ .se_snprintf = hist_entry__local_weight_snprintf,
+ .se_width_idx = HISTC_LOCAL_WEIGHT,
+};
+
+static int64_t
+sort__global_weight_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+ return left->stat.weight - right->stat.weight;
+}
+
+static int hist_entry__global_weight_snprintf(struct hist_entry *self, char *bf,
+ size_t size, unsigned int width)
+{
+ return repsep_snprintf(bf, size, "%-*llu", width, self->stat.weight);
+}
+
+struct sort_entry sort_global_weight = {
+ .se_header = "Weight",
+ .se_cmp = sort__global_weight_cmp,
+ .se_snprintf = hist_entry__global_weight_snprintf,
+ .se_width_idx = HISTC_GLOBAL_WEIGHT,
+};
+
struct sort_dimension {
const char *name;
struct sort_entry *entry;
@@ -480,6 +523,8 @@ static struct sort_dimension common_sort_dimensions[] = {
DIM(SORT_PARENT, "parent", sort_parent),
DIM(SORT_CPU, "cpu", sort_cpu),
DIM(SORT_SRCLINE, "srcline", sort_srcline),
+ DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
+ DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
};
#undef DIM
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index b13e56f6ccb..39392501279 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -49,6 +49,7 @@ struct he_stat {
u64 period_us;
u64 period_guest_sys;
u64 period_guest_us;
+ u64 weight;
u32 nr_events;
};
@@ -130,6 +131,8 @@ enum sort_type {
SORT_PARENT,
SORT_CPU,
SORT_SRCLINE,
+ SORT_LOCAL_WEIGHT,
+ SORT_GLOBAL_WEIGHT,
/* branch stack specific sort keys */
__SORT_BRANCH_STACK,