lkml.org 
[lkml]   [2017]   [Mar]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 05/13] perf, tools: Expand PMU events by prefix match
    Date
    From: Andi Kleen <ak@linux.intel.com>

    When the user specifies a pmu directly, expand it automatically
    with a prefix match for all available PMUs, similar as we do for
    the normal aliases now.

    This allows to specify attributes for duplicated boxes quickly.
    For example uncore_cbox_{0,6}/.../ can be now specified as uncore_cbox/.../
    and it gets automatically expanded for all boxes.

    This generally makes it more concise to write uncore specifications, and
    also avoids the need to know the exact topology of the system.

    Before

    % perf stat -a -e uncore_cbox_0/event=0x35,umask=0x1,filter_opc=0x19C/,\
    uncore_cbox_1/event=0x35,umask=0x1,filter_opc=0x19C/,\
    uncore_cbox_2/event=0x35,umask=0x1,filter_opc=0x19C/,\
    uncore_cbox_3/event=0x35,umask=0x1,filter_opc=0x19C/,\
    uncore_cbox_4/event=0x35,umask=0x1,filter_opc=0x19C/,\
    uncore_cbox_5/event=0x35,umask=0x1,filter_opc=0x19C/ sleep 1

    After

    % perf stat -a -e uncore_cbox/event=0x35,umask=0x1,filter_opc=0x19C/ sleep 1

    v2: Handle all bison rules. Move multi add code to separate function.
    Handle uncore_ prefix correctly.
    v3: Move parse_events_multi_pmu_add to separate patch. Move uncore
    prefix check to separate patch.
    Signed-off-by: Andi Kleen <ak@linux.intel.com>
    ---
    tools/perf/util/parse-events.c | 25 +++++++++++++++++++++++++
    tools/perf/util/parse-events.h | 3 +++
    tools/perf/util/parse-events.y | 40 ++++++++++++++++++++++++++--------------
    3 files changed, 54 insertions(+), 14 deletions(-)

    diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
    index c3edb373ed86..e594c974c93e 100644
    --- a/tools/perf/util/parse-events.c
    +++ b/tools/perf/util/parse-events.c
    @@ -2462,6 +2462,31 @@ int parse_events_term__clone(struct parse_events_term **new,
    return new_term(new, &temp, term->val.str, term->val.num);
    }

    +int parse_events_copy_term_list(struct list_head *old,
    + struct list_head **new)
    +{
    + struct parse_events_term *term, *n;
    + int ret;
    +
    + if (!old) {
    + *new = NULL;
    + return 0;
    + }
    +
    + *new = malloc(sizeof(struct list_head));
    + if (!*new)
    + return -ENOMEM;
    + INIT_LIST_HEAD(*new);
    +
    + list_for_each_entry (term, old, list) {
    + ret = parse_events_term__clone(&n, term);
    + if (ret)
    + return ret;
    + list_add_tail(&n->list, *new);
    + }
    + return 0;
    +}
    +
    void parse_events_terms__purge(struct list_head *terms)
    {
    struct parse_events_term *term, *h;
    diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h
    index deca9ce965a7..f38086b8dbea 100644
    --- a/tools/perf/util/parse-events.h
    +++ b/tools/perf/util/parse-events.h
    @@ -172,6 +172,9 @@ int parse_events_multi_pmu_add(struct parse_events_evlist *data,
    char *str,
    struct list_head **listp);

    +int parse_events_copy_term_list(struct list_head *old,
    + struct list_head **new);
    +
    enum perf_pmu_event_symbol_type
    perf_pmu__parse_check(const char *name);
    void parse_events__set_leader(char *name, struct list_head *list);
    diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y
    index 36af02f95243..20935b17753d 100644
    --- a/tools/perf/util/parse-events.y
    +++ b/tools/perf/util/parse-events.y
    @@ -226,11 +226,32 @@ event_pmu:
    PE_NAME opt_event_config
    {
    struct parse_events_evlist *data = _data;
    - struct list_head *list;
    + struct list_head *list, *orig_terms, *terms;
    +
    + if (parse_events_copy_term_list($2, &orig_terms))
    + YYABORT;

    ALLOC_LIST(list);
    - ABORT_ON(parse_events_add_pmu(data, list, $1, $2));
    + if (parse_events_add_pmu(data, list, $1, $2)) {
    + struct perf_pmu *pmu = NULL;
    + int ok = 0;
    +
    + while ((pmu = perf_pmu__scan(pmu)) != NULL) {
    + char *name = pmu->name;
    +
    + if (!strncmp($1, name, strlen($1))) {
    + if (parse_events_copy_term_list(orig_terms, &terms))
    + YYABORT;
    + if (!parse_events_add_pmu(data, list, pmu->name, terms))
    + ok++;
    + parse_events_terms__delete(terms);
    + }
    + }
    + if (!ok)
    + YYABORT;
    + }
    parse_events_terms__delete($2);
    + parse_events_terms__delete(orig_terms);
    $$ = list;
    }
    |
    @@ -245,21 +266,12 @@ PE_KERNEL_PMU_EVENT sep_dc
    |
    PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc
    {
    - struct parse_events_evlist *data = _data;
    - struct list_head *head;
    - struct parse_events_term *term;
    struct list_head *list;
    char pmu_name[128];
    - snprintf(&pmu_name, 128, "%s-%s", $1, $3);

    - ALLOC_LIST(head);
    - ABORT_ON(parse_events_term__num(&term, PARSE_EVENTS__TERM_TYPE_USER,
    - &pmu_name, 1, false, &@1, NULL));
    - list_add_tail(&term->list, head);
    -
    - ALLOC_LIST(list);
    - ABORT_ON(parse_events_add_pmu(data, list, "cpu", head));
    - parse_events_terms__delete(head);
    + snprintf(&pmu_name, 128, "%s-%s", $1, $3);
    + if (parse_events_multi_pmu_add(_data, pmu_name, &list) < 0)
    + YYABORT;
    $$ = list;
    }

    --
    2.9.3
    \
     
     \ /
      Last update: 2017-03-20 21:19    [W:4.071 / U:0.344 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site