lkml.org 
[lkml]   [2020]   [Apr]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[RFC PATCH v2 03/13] perf jevents: Add support for system events tables
    Date
    Process the JSONs to find support for "system" events, which are not tied
    to a specific CPUID.

    We now use a "COMPAT" property to match against the namespace ID from the
    kernel PMU driver.

    The generated pmu-events.c will now have 2 tables: a. As before, we will
    have the event table for CPU events. b. New pmu_sys_event_tables[] table,
    which will have events matched to SoCs.

    It will look like this:

    struct pmu_event pme_hisilicon_hip08_sys[] = {
    {
    .name = "cycles",
    .compat = "HIP08",
    .event = "event=0",
    .desc = "Clock cycles",
    .topic = "smmu v3 pmcg",
    .long_desc = "Clock cycles",
    },
    {
    .name = "smmuv3_pmcg.l1_tlb",
    .compat = "HIP08",
    .event = "event=0x8a",
    .desc = "SMMUv3 PMCG l1_tlb. Unit: smmuv3_pmcg ",
    .topic = "smmu v3 pmcg",
    .long_desc = "SMMUv3 PMCG l1_tlb",
    .pmu = "smmuv3_pmcg",
    },
    ...
    };

    struct pmu_event pme_arm_cortex_a53[] = {
    {
    .name = "ext_mem_req",
    .event = "event=0xc0",
    .desc = "External memory request",
    .topic = "memory",
    },
    {
    .name = "ext_mem_req_nc",
    .event = "event=0xc1",
    .desc = "Non-cacheable external memory request",
    .topic = "memory",
    },
    ...
    };

    struct pmu_event pme_hisilicon_hip08_cpu[] = {
    {
    .name = "l2d_cache_refill_wr",
    .event = "event=0x53",
    .desc = "L2D cache refill, write",
    .topic = "core imp def",
    .long_desc = "Attributable Level 2 data cache refill, write",
    },
    ...
    };

    struct pmu_events_map pmu_events_map[] = {
    {
    .cpuid = "0x00000000410fd030",
    .version = "v1",
    .type = "core",
    .table = pme_arm_cortex_a53
    },
    {
    .cpuid = "0x00000000480fd010",
    .version = "v1",
    .type = "core",
    .table = pme_hisilicon_hip08_cpu
    },
    {
    .table = 0
    },
    };

    struct pmu_event pme_hisilicon_hip08_cpu[] = {
    {
    .name = "uncore_hisi_l3c.rd_cpipe",
    .event = "event=0",
    .desc = "Total read accesses. Unit: hisi_sccl,l3c ",
    .topic = "uncore l3c",
    .long_desc = "Total read accesses",
    .pmu = "hisi_sccl,l3c",
    },
    {
    .name = "uncore_hisi_l3c.wr_cpipe",
    .event = "event=0x1",
    .desc = "Total write accesses. Unit: hisi_sccl,l3c ",
    .topic = "uncore l3c",
    .long_desc = "Total write accesses",
    .pmu = "hisi_sccl,l3c",
    },
    ...
    };


    struct pmu_sys_events pmu_sys_event_tables[] = {
    {
    .table = pme_hisilicon_hip08_sys,
    },
    ...
    };

    Signed-off-by: John Garry <john.garry@huawei.com>
    ---
    tools/perf/pmu-events/jevents.c | 138 ++++++++++++++++++++++++++++---------
    tools/perf/pmu-events/jevents.h | 11 ++-
    tools/perf/pmu-events/pmu-events.h | 6 ++
    3 files changed, 118 insertions(+), 37 deletions(-)

    diff --git a/tools/perf/pmu-events/jevents.c b/tools/perf/pmu-events/jevents.c
    index c7868d0a7a6b..acb6b77bddc0 100644
    --- a/tools/perf/pmu-events/jevents.c
    +++ b/tools/perf/pmu-events/jevents.c
    @@ -53,6 +53,23 @@
    int verbose;
    char *prog;

    +static LIST_HEAD(sys_event_tables);
    +
    +struct sys_event_table {
    + struct list_head list;
    + char *name;
    +};
    +
    +static void free_sys_event_tables(void)
    +{
    + struct sys_event_table *et, *next;
    +
    + list_for_each_entry_safe(et, next, &sys_event_tables, list) {
    + free(et->name);
    + free(et);
    + }
    +}
    +
    int eprintf(int level, int var, const char *fmt, ...)
    {

    @@ -318,12 +335,12 @@ static void print_events_table_prefix(FILE *fp, const char *tblname)
    close_table = 1;
    }

    -static int print_events_table_entry(void *data, char *name, char *event,
    - char *desc, char *long_desc,
    +static int print_events_table_entry(void *data, char *name, char *compat,
    + char *event, char *desc, char *long_desc,
    char *pmu, char *unit, char *perpkg,
    - char *metric_expr,
    - char *metric_name, char *metric_group,
    - char *deprecated, char *metric_constraint)
    + char *metric_expr, char *metric_name,
    + char *metric_group, char *deprecated,
    + char *metric_constraint)
    {
    struct perf_entry_data *pd = data;
    FILE *outfp = pd->outfp;
    @@ -337,6 +354,9 @@ static int print_events_table_entry(void *data, char *name, char *event,

    if (name)
    fprintf(outfp, "\t.name = \"%s\",\n", name);
    + if (compat)
    + fprintf(outfp, "\t.compat = \"%s\",\n", compat);
    +
    if (event)
    fprintf(outfp, "\t.event = \"%s\",\n", event);
    fprintf(outfp, "\t.desc = \"%s\",\n", desc);
    @@ -367,6 +387,7 @@ static int print_events_table_entry(void *data, char *name, char *event,
    struct event_struct {
    struct list_head list;
    char *name;
    + char *compat;
    char *event;
    char *desc;
    char *long_desc;
    @@ -421,11 +442,12 @@ static void free_arch_std_events(void)
    }
    }

    -static int save_arch_std_events(void *data, char *name, char *event,
    - char *desc, char *long_desc, char *pmu,
    - char *unit, char *perpkg, char *metric_expr,
    - char *metric_name, char *metric_group,
    - char *deprecated, char *metric_constraint)
    +static int save_arch_std_events(void *data, char *name, char *compat,
    + char *event, char *desc, char *long_desc,
    + char *pmu, char *unit, char *perpkg,
    + char *metric_expr, char *metric_name,
    + char *metric_group, char *deprecated,
    + char *metric_constraint)
    {
    struct event_struct *es;

    @@ -513,12 +535,11 @@ try_fixup(const char *fn, char *arch_std, char **event, char **desc,

    /* Call func with each event in the json file */
    int json_events(const char *fn,
    - int (*func)(void *data, char *name, char *event, char *desc,
    - char *long_desc,
    - char *pmu, char *unit, char *perpkg,
    - char *metric_expr,
    - char *metric_name, char *metric_group,
    - char *deprecated, char *metric_constraint),
    + int (*func)(void *data, char *name, char *compat, char *event,
    + char *desc, char *long_desc, char *pmu, char *unit,
    + char *perpkg, char *metric_expr, char *metric_name,
    + char *metric_group, char *deprecated,
    + char *metric_constraint),
    void *data)
    {
    int err;
    @@ -537,7 +558,7 @@ int json_events(const char *fn,
    EXPECT(tokens->type == JSMN_ARRAY, tokens, "expected top level array");
    tok = tokens + 1;
    for (i = 0; i < tokens->size; i++) {
    - char *event = NULL, *desc = NULL, *name = NULL;
    + char *event = NULL, *desc = NULL, *name = NULL, *compat = NULL;
    char *long_desc = NULL;
    char *extra_desc = NULL;
    char *pmu = NULL;
    @@ -584,6 +605,8 @@ int json_events(const char *fn,
    free(code);
    } else if (json_streq(map, field, "EventName")) {
    addfield(map, &name, "", "", val);
    + } else if (json_streq(map, field, "Compat")) {
    + addfield(map, &compat, "", "", val);
    } else if (json_streq(map, field, "BriefDescription")) {
    addfield(map, &desc, "", "", val);
    fixdesc(desc);
    @@ -680,13 +703,15 @@ int json_events(const char *fn,
    if (err)
    goto free_strings;
    }
    - err = func(data, name, real_event(name, event), desc, long_desc,
    - pmu, unit, perpkg, metric_expr, metric_name,
    - metric_group, deprecated, metric_constraint);
    + err = func(data, name, compat, real_event(name, event), desc,
    + long_desc, pmu, unit, perpkg, metric_expr,
    + metric_name, metric_group, deprecated,
    + metric_constraint);
    free_strings:
    + free(name);
    + free(compat);
    free(event);
    free(desc);
    - free(name);
    free(long_desc);
    free(extra_desc);
    free(pmu);
    @@ -750,6 +775,25 @@ static char *file_name_to_table_name(char *fname)
    return tblname;
    }

    +static bool is_sys_dir(char *fname)
    +{
    + char *pos;
    +
    + while (true) {
    + pos = strchr(fname, '/');
    +
    + if (!pos) {
    + if (!strcmp(fname, "sys"))
    + return true;
    + return false;
    + }
    +
    + fname = pos + 1;
    + }
    +
    + return false;
    +}
    +
    static void print_mapping_table_prefix(FILE *outfp)
    {
    fprintf(outfp, "struct pmu_events_map pmu_events_map[] = {\n");
    @@ -784,6 +828,23 @@ static void print_mapping_test_table(FILE *outfp)
    fprintf(outfp, "},\n");
    }

    +static int process_system_event_tables(FILE *outfp)
    +{
    + struct sys_event_table *sys_event_table;
    +
    + fprintf(outfp, "struct pmu_sys_events pmu_sys_event_tables[] = {");
    +
    + list_for_each_entry(sys_event_table, &sys_event_tables, list) {
    + fprintf(outfp, "\n\t{\n\t\t.table = %s,\n\t},",
    + sys_event_table->name);
    + }
    + fprintf(outfp, "\n\t{\n\t\t.table = 0\n\t},");
    +
    + fprintf(outfp, "\n};\n");
    +
    + return 0;
    +}
    +
    static int process_mapfile(FILE *outfp, char *fpath)
    {
    int n = 16384;
    @@ -1029,6 +1090,18 @@ static int process_one_file(const char *fpath, const struct stat *sb,
    return -1;
    }

    + if (is_sys_dir(bname)) {
    + struct sys_event_table *sys_event_table;
    +
    + sys_event_table = malloc(sizeof(*sys_event_table));
    + if (!sys_event_table)
    + return -1;
    +
    + sys_event_table->name = strdup(tblname);
    + list_add_tail(&sys_event_table->list,
    + &sys_event_tables);
    + }
    +
    print_events_table_prefix(eventsfp, tblname);
    return 0;
    }
    @@ -1180,7 +1253,6 @@ int main(int argc, char *argv[])
    } else if (rc < 0) {
    /* Make build fail */
    fclose(eventsfp);
    - free_arch_std_events();
    ret = 1;
    goto out_free_mapfile;
    } else if (rc) {
    @@ -1206,27 +1278,31 @@ int main(int argc, char *argv[])
    if (close_table)
    print_events_table_suffix(eventsfp);

    - if (!mapfile) {
    - pr_info("%s: No CPU->JSON mapping?\n", prog);
    - goto empty_map;
    + if (mapfile) {
    + if (process_mapfile(eventsfp, mapfile)) {
    + pr_err("%s: Error processing mapfile %s\n", prog,
    + mapfile);
    + /* Make build fail */
    + fclose(eventsfp);
    + ret = 1;
    + }
    + } else {
    + pr_err("%s: No CPU->JSON mapping?\n", prog);
    }

    - if (process_mapfile(eventsfp, mapfile)) {
    - pr_info("%s: Error processing mapfile %s\n", prog, mapfile);
    - /* Make build fail */
    + if (process_system_event_tables(eventsfp)) {
    fclose(eventsfp);
    - free_arch_std_events();
    ret = 1;
    }

    -
    goto out_free_mapfile;

    empty_map:
    fclose(eventsfp);
    create_empty_mapping(output_file);
    - free_arch_std_events();
    out_free_mapfile:
    + free_arch_std_events();
    + free_sys_event_tables();
    free(mapfile);
    return ret;
    }
    diff --git a/tools/perf/pmu-events/jevents.h b/tools/perf/pmu-events/jevents.h
    index 2afc8304529e..7e324b210747 100644
    --- a/tools/perf/pmu-events/jevents.h
    +++ b/tools/perf/pmu-events/jevents.h
    @@ -3,12 +3,11 @@
    #define JEVENTS_H 1

    int json_events(const char *fn,
    - int (*func)(void *data, char *name, char *event, char *desc,
    - char *long_desc,
    - char *pmu,
    - char *unit, char *perpkg, char *metric_expr,
    - char *metric_name, char *metric_group,
    - char *deprecated, char *metric_constraint),
    + int (*func)(void *data, char *name, char *compat, char *event,
    + char *desc, char *long_desc, char *pmu, char *unit,
    + char *perpkg, char *metric_expr, char *metric_name,
    + char *metric_group, char *deprecated,
    + char *metric_constraint),
    void *data);
    char *get_cpu_str(void);

    diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu-events.h
    index 53e76d5d5b37..cc6de8c5af49 100644
    --- a/tools/perf/pmu-events/pmu-events.h
    +++ b/tools/perf/pmu-events/pmu-events.h
    @@ -7,6 +7,7 @@
    */
    struct pmu_event {
    const char *name;
    + const char *compat;
    const char *event;
    const char *desc;
    const char *topic;
    @@ -37,10 +38,15 @@ struct pmu_events_map {
    struct pmu_event *table;
    };

    +struct pmu_sys_events {
    + struct pmu_event *table;
    +};
    +
    /*
    * Global table mapping each known CPU for the architecture to its
    * table of PMU events.
    */
    extern struct pmu_events_map pmu_events_map[];
    +extern struct pmu_sys_events pmu_sys_event_tables[];

    #endif
    --
    2.16.4
    \
     
     \ /
      Last update: 2020-04-17 12:46    [W:5.639 / U:0.056 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site