lkml.org 
[lkml]   [2016]   [Feb]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 12/23] perf hists: Introduce hist_entry__filter()
    Date
    The hist_entry__filter() function is to filter hist entries using
    sort key relatd 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.

    Acked-by: Pekka Enberg <penberg@kernel.org>
    Signed-off-by: Namhyung Kim <namhyung@kernel.org>
    ---
    tools/perf/util/hist.h | 2 +
    tools/perf/util/sort.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++
    tools/perf/util/sort.h | 1 +
    3 files changed, 116 insertions(+)

    diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
    index adfc9931e186..0bf60c3bf895 100644
    --- a/tools/perf/util/hist.h
    +++ b/tools/perf/util/hist.h
    @@ -297,6 +297,8 @@ bool perf_hpp__is_sort_entry(struct perf_hpp_fmt *format);
    bool perf_hpp__is_dynamic_entry(struct perf_hpp_fmt *format);
    bool perf_hpp__defined_dynamic_entry(struct perf_hpp_fmt *fmt, struct hists *hists);

    +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,
    struct hists *hists)
    {
    diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
    index de620f7f40f4..cef3b6329a35 100644
    --- a/tools/perf/util/sort.c
    +++ b/tools/perf/util/sort.c
    @@ -81,10 +81,21 @@ static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
    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 = {
    .se_header = " Pid:Command",
    .se_cmp = sort__thread_cmp,
    .se_snprintf = hist_entry__thread_snprintf,
    + .se_filter = hist_entry__thread_filter,
    .se_width_idx = HISTC_THREAD,
    };

    @@ -122,6 +133,7 @@ struct sort_entry sort_comm = {
    .se_collapse = sort__comm_collapse,
    .se_sort = sort__comm_sort,
    .se_snprintf = hist_entry__comm_snprintf,
    + .se_filter = hist_entry__thread_filter,
    .se_width_idx = HISTC_COMM,
    };

    @@ -171,10 +183,21 @@ static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf,
    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 = {
    .se_header = "Shared Object",
    .se_cmp = sort__dso_cmp,
    .se_snprintf = hist_entry__dso_snprintf,
    + .se_filter = hist_entry__dso_filter,
    .se_width_idx = HISTC_DSO,
    };

    @@ -275,11 +298,22 @@ static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
    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 = {
    .se_header = "Symbol",
    .se_cmp = sort__sym_cmp,
    .se_sort = sort__sym_sort,
    .se_snprintf = hist_entry__sym_snprintf,
    + .se_filter = hist_entry__sym_filter,
    .se_width_idx = HISTC_SYMBOL,
    };

    @@ -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);
    }

    +static int hist_entry__socket_filter(struct hist_entry *he, int type, const void *arg)
    +{
    + int socket = *(const int *)arg;
    +
    + if (type != HIST_FILTER__SOCKET)
    + return -1;
    +
    + return socket >= 0 && he->socket != socket;
    +}
    +
    struct sort_entry sort_socket = {
    .se_header = "Socket",
    .se_cmp = sort__socket_cmp,
    .se_snprintf = hist_entry__socket_snprintf,
    + .se_filter = hist_entry__socket_filter,
    .se_width_idx = HISTC_SOCKET,
    };

    @@ -533,6 +578,18 @@ static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
    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
    sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
    {
    @@ -553,6 +610,18 @@ static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
    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
    sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
    {
    @@ -614,10 +683,35 @@ static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
    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 = {
    .se_header = "Source Shared Object",
    .se_cmp = sort__dso_from_cmp,
    .se_snprintf = hist_entry__dso_from_snprintf,
    + .se_filter = hist_entry__dso_from_filter,
    .se_width_idx = HISTC_DSO_FROM,
    };

    @@ -625,6 +719,7 @@ struct sort_entry sort_dso_to = {
    .se_header = "Target Shared Object",
    .se_cmp = sort__dso_to_cmp,
    .se_snprintf = hist_entry__dso_to_snprintf,
    + .se_filter = hist_entry__dso_to_filter,
    .se_width_idx = HISTC_DSO_TO,
    };

    @@ -632,6 +727,7 @@ struct sort_entry sort_sym_from = {
    .se_header = "Source Symbol",
    .se_cmp = sort__sym_from_cmp,
    .se_snprintf = hist_entry__sym_from_snprintf,
    + .se_filter = hist_entry__sym_from_filter,
    .se_width_idx = HISTC_SYMBOL_FROM,
    };

    @@ -639,6 +735,7 @@ struct sort_entry sort_sym_to = {
    .se_header = "Target Symbol",
    .se_cmp = sort__sym_to_cmp,
    .se_snprintf = hist_entry__sym_to_snprintf,
    + .se_filter = hist_entry__sym_to_filter,
    .se_width_idx = HISTC_SYMBOL_TO,
    };

    @@ -1605,6 +1702,22 @@ static struct perf_hpp_fmt *__hpp_dimension__alloc_hpp(struct hpp_dimension *hd)
    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)
    {
    struct hpp_sort_entry *hse = __sort_dimension__alloc_hpp(sd);
    diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
    index 0cdfd0cfe783..ce962743c087 100644
    --- a/tools/perf/util/sort.h
    +++ b/tools/perf/util/sort.h
    @@ -234,6 +234,7 @@ struct sort_entry {
    int64_t (*se_sort)(struct hist_entry *, struct hist_entry *);
    int (*se_snprintf)(struct hist_entry *he, char *bf, size_t size,
    unsigned int width);
    + int (*se_filter)(struct hist_entry *he, int type, const void *arg);
    u8 se_width_idx;
    };

    --
    2.7.0
    \
     
     \ /
      Last update: 2016-02-05 14:41    [W:4.321 / U:0.532 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site