Commit 54430101 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo

perf hists: Introduce hist_entry__filter()

The hist_entry__filter() function is to filter hist entries using sort
key related info.  This is needed to support hierarchy mode since each
hist entry will be associated with a hpp fmt which has a sort key.  So
each entry should compare to only matching type of filters.

To do that, add the ->se_filter callback field to struct sort_entry.
This callback takes 'type' argument which determines whether it's
matching sort key or not.  It returns -1 for non-matching type, 0 for
filtered entry and 1 for not filtered entries.
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Acked-by: default avatarPekka Enberg <penberg@kernel.org>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1456326830-30456-6-git-send-email-namhyung@kernel.org
[ 'socket' is reserved in sys/socket.h, so replace it with 'sk' ]
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 8c01872f
...@@ -305,6 +305,8 @@ bool perf_hpp__is_trace_entry(struct perf_hpp_fmt *fmt); ...@@ -305,6 +305,8 @@ bool perf_hpp__is_trace_entry(struct perf_hpp_fmt *fmt);
bool perf_hpp__is_srcline_entry(struct perf_hpp_fmt *fmt); bool perf_hpp__is_srcline_entry(struct perf_hpp_fmt *fmt);
bool perf_hpp__is_srcfile_entry(struct perf_hpp_fmt *fmt); bool perf_hpp__is_srcfile_entry(struct perf_hpp_fmt *fmt);
int hist_entry__filter(struct hist_entry *he, int type, const void *arg);
static inline bool perf_hpp__should_skip(struct perf_hpp_fmt *format, static inline bool perf_hpp__should_skip(struct perf_hpp_fmt *format,
struct hists *hists) struct hists *hists)
{ {
......
...@@ -90,10 +90,21 @@ static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf, ...@@ -90,10 +90,21 @@ static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
width, width, comm ?: ""); width, width, comm ?: "");
} }
static int hist_entry__thread_filter(struct hist_entry *he, int type, const void *arg)
{
const struct thread *th = arg;
if (type != HIST_FILTER__THREAD)
return -1;
return th && he->thread != th;
}
struct sort_entry sort_thread = { struct sort_entry sort_thread = {
.se_header = " Pid:Command", .se_header = " Pid:Command",
.se_cmp = sort__thread_cmp, .se_cmp = sort__thread_cmp,
.se_snprintf = hist_entry__thread_snprintf, .se_snprintf = hist_entry__thread_snprintf,
.se_filter = hist_entry__thread_filter,
.se_width_idx = HISTC_THREAD, .se_width_idx = HISTC_THREAD,
}; };
...@@ -131,6 +142,7 @@ struct sort_entry sort_comm = { ...@@ -131,6 +142,7 @@ struct sort_entry sort_comm = {
.se_collapse = sort__comm_collapse, .se_collapse = sort__comm_collapse,
.se_sort = sort__comm_sort, .se_sort = sort__comm_sort,
.se_snprintf = hist_entry__comm_snprintf, .se_snprintf = hist_entry__comm_snprintf,
.se_filter = hist_entry__thread_filter,
.se_width_idx = HISTC_COMM, .se_width_idx = HISTC_COMM,
}; };
...@@ -180,10 +192,21 @@ static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf, ...@@ -180,10 +192,21 @@ static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf,
return _hist_entry__dso_snprintf(he->ms.map, bf, size, width); return _hist_entry__dso_snprintf(he->ms.map, bf, size, width);
} }
static int hist_entry__dso_filter(struct hist_entry *he, int type, const void *arg)
{
const struct dso *dso = arg;
if (type != HIST_FILTER__DSO)
return -1;
return dso && (!he->ms.map || he->ms.map->dso != dso);
}
struct sort_entry sort_dso = { struct sort_entry sort_dso = {
.se_header = "Shared Object", .se_header = "Shared Object",
.se_cmp = sort__dso_cmp, .se_cmp = sort__dso_cmp,
.se_snprintf = hist_entry__dso_snprintf, .se_snprintf = hist_entry__dso_snprintf,
.se_filter = hist_entry__dso_filter,
.se_width_idx = HISTC_DSO, .se_width_idx = HISTC_DSO,
}; };
...@@ -277,11 +300,22 @@ static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf, ...@@ -277,11 +300,22 @@ static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
he->level, bf, size, width); he->level, bf, size, width);
} }
static int hist_entry__sym_filter(struct hist_entry *he, int type, const void *arg)
{
const char *sym = arg;
if (type != HIST_FILTER__SYMBOL)
return -1;
return sym && (!he->ms.sym || !strstr(he->ms.sym->name, sym));
}
struct sort_entry sort_sym = { struct sort_entry sort_sym = {
.se_header = "Symbol", .se_header = "Symbol",
.se_cmp = sort__sym_cmp, .se_cmp = sort__sym_cmp,
.se_sort = sort__sym_sort, .se_sort = sort__sym_sort,
.se_snprintf = hist_entry__sym_snprintf, .se_snprintf = hist_entry__sym_snprintf,
.se_filter = hist_entry__sym_filter,
.se_width_idx = HISTC_SYMBOL, .se_width_idx = HISTC_SYMBOL,
}; };
...@@ -440,10 +474,21 @@ static int hist_entry__socket_snprintf(struct hist_entry *he, char *bf, ...@@ -440,10 +474,21 @@ static int hist_entry__socket_snprintf(struct hist_entry *he, char *bf,
return repsep_snprintf(bf, size, "%*.*d", width, width-3, he->socket); return repsep_snprintf(bf, size, "%*.*d", width, width-3, he->socket);
} }
static int hist_entry__socket_filter(struct hist_entry *he, int type, const void *arg)
{
int sk = *(const int *)arg;
if (type != HIST_FILTER__SOCKET)
return -1;
return sk >= 0 && he->socket != sk;
}
struct sort_entry sort_socket = { struct sort_entry sort_socket = {
.se_header = "Socket", .se_header = "Socket",
.se_cmp = sort__socket_cmp, .se_cmp = sort__socket_cmp,
.se_snprintf = hist_entry__socket_snprintf, .se_snprintf = hist_entry__socket_snprintf,
.se_filter = hist_entry__socket_filter,
.se_width_idx = HISTC_SOCKET, .se_width_idx = HISTC_SOCKET,
}; };
...@@ -530,6 +575,18 @@ static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf, ...@@ -530,6 +575,18 @@ static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
} }
static int hist_entry__dso_from_filter(struct hist_entry *he, int type,
const void *arg)
{
const struct dso *dso = arg;
if (type != HIST_FILTER__DSO)
return -1;
return dso && (!he->branch_info || !he->branch_info->from.map ||
he->branch_info->from.map->dso != dso);
}
static int64_t static int64_t
sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right) sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
{ {
...@@ -550,6 +607,18 @@ static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf, ...@@ -550,6 +607,18 @@ static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
} }
static int hist_entry__dso_to_filter(struct hist_entry *he, int type,
const void *arg)
{
const struct dso *dso = arg;
if (type != HIST_FILTER__DSO)
return -1;
return dso && (!he->branch_info || !he->branch_info->to.map ||
he->branch_info->to.map->dso != dso);
}
static int64_t static int64_t
sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right) sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
{ {
...@@ -611,10 +680,35 @@ static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf, ...@@ -611,10 +680,35 @@ static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A"); return repsep_snprintf(bf, size, "%-*.*s", width, width, "N/A");
} }
static int hist_entry__sym_from_filter(struct hist_entry *he, int type,
const void *arg)
{
const char *sym = arg;
if (type != HIST_FILTER__SYMBOL)
return -1;
return sym && !(he->branch_info && he->branch_info->from.sym &&
strstr(he->branch_info->from.sym->name, sym));
}
static int hist_entry__sym_to_filter(struct hist_entry *he, int type,
const void *arg)
{
const char *sym = arg;
if (type != HIST_FILTER__SYMBOL)
return -1;
return sym && !(he->branch_info && he->branch_info->to.sym &&
strstr(he->branch_info->to.sym->name, sym));
}
struct sort_entry sort_dso_from = { struct sort_entry sort_dso_from = {
.se_header = "Source Shared Object", .se_header = "Source Shared Object",
.se_cmp = sort__dso_from_cmp, .se_cmp = sort__dso_from_cmp,
.se_snprintf = hist_entry__dso_from_snprintf, .se_snprintf = hist_entry__dso_from_snprintf,
.se_filter = hist_entry__dso_from_filter,
.se_width_idx = HISTC_DSO_FROM, .se_width_idx = HISTC_DSO_FROM,
}; };
...@@ -622,6 +716,7 @@ struct sort_entry sort_dso_to = { ...@@ -622,6 +716,7 @@ struct sort_entry sort_dso_to = {
.se_header = "Target Shared Object", .se_header = "Target Shared Object",
.se_cmp = sort__dso_to_cmp, .se_cmp = sort__dso_to_cmp,
.se_snprintf = hist_entry__dso_to_snprintf, .se_snprintf = hist_entry__dso_to_snprintf,
.se_filter = hist_entry__dso_to_filter,
.se_width_idx = HISTC_DSO_TO, .se_width_idx = HISTC_DSO_TO,
}; };
...@@ -629,6 +724,7 @@ struct sort_entry sort_sym_from = { ...@@ -629,6 +724,7 @@ struct sort_entry sort_sym_from = {
.se_header = "Source Symbol", .se_header = "Source Symbol",
.se_cmp = sort__sym_from_cmp, .se_cmp = sort__sym_from_cmp,
.se_snprintf = hist_entry__sym_from_snprintf, .se_snprintf = hist_entry__sym_from_snprintf,
.se_filter = hist_entry__sym_from_filter,
.se_width_idx = HISTC_SYMBOL_FROM, .se_width_idx = HISTC_SYMBOL_FROM,
}; };
...@@ -636,6 +732,7 @@ struct sort_entry sort_sym_to = { ...@@ -636,6 +732,7 @@ struct sort_entry sort_sym_to = {
.se_header = "Target Symbol", .se_header = "Target Symbol",
.se_cmp = sort__sym_to_cmp, .se_cmp = sort__sym_to_cmp,
.se_snprintf = hist_entry__sym_to_snprintf, .se_snprintf = hist_entry__sym_to_snprintf,
.se_filter = hist_entry__sym_to_filter,
.se_width_idx = HISTC_SYMBOL_TO, .se_width_idx = HISTC_SYMBOL_TO,
}; };
...@@ -1498,6 +1595,22 @@ static struct perf_hpp_fmt *__hpp_dimension__alloc_hpp(struct hpp_dimension *hd) ...@@ -1498,6 +1595,22 @@ static struct perf_hpp_fmt *__hpp_dimension__alloc_hpp(struct hpp_dimension *hd)
return fmt; return fmt;
} }
int hist_entry__filter(struct hist_entry *he, int type, const void *arg)
{
struct perf_hpp_fmt *fmt;
struct hpp_sort_entry *hse;
fmt = he->fmt;
if (fmt == NULL || !perf_hpp__is_sort_entry(fmt))
return -1;
hse = container_of(fmt, struct hpp_sort_entry, hpp);
if (hse->se->se_filter == NULL)
return -1;
return hse->se->se_filter(he, type, arg);
}
static int __sort_dimension__add_hpp_sort(struct sort_dimension *sd) static int __sort_dimension__add_hpp_sort(struct sort_dimension *sd)
{ {
struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd); struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd);
......
...@@ -245,6 +245,7 @@ struct sort_entry { ...@@ -245,6 +245,7 @@ struct sort_entry {
int64_t (*se_sort)(struct hist_entry *, struct hist_entry *); int64_t (*se_sort)(struct hist_entry *, struct hist_entry *);
int (*se_snprintf)(struct hist_entry *he, char *bf, size_t size, int (*se_snprintf)(struct hist_entry *he, char *bf, size_t size,
unsigned int width); unsigned int width);
int (*se_filter)(struct hist_entry *he, int type, const void *arg);
u8 se_width_idx; u8 se_width_idx;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment