lkml.org 
[lkml]   [2024]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Date
    SubjectRe: [RFC PATCH v3 08/18] perf stat: Add functions to get counter info
    On Tue, Dec 12, 2023 at 3:03 PM <weilin.wang@intel.com> wrote:
    >
    > From: Weilin Wang <weilin.wang@intel.com>
    >
    > Add data structure metricgroup__pmu_counters to represent hardware counters
    > available in the system.
    >
    > Add functions to parse pmu-events and create the list of pmu_info_list to
    > hold the counter information of the system.
    >
    > Add functions to free pmu_info_list and event_info_list before exit
    > grouping for hardware-grouping method
    >
    > This method would fall back to normal grouping when event json files do not
    > support hardware aware grouping.
    >
    > Signed-off-by: Weilin Wang <weilin.wang@intel.com>
    > ---
    > tools/perf/util/metricgroup.c | 85 +++++++++++++++++++++++++++++++++--
    > tools/perf/util/metricgroup.h | 15 +++++++
    > 2 files changed, 97 insertions(+), 3 deletions(-)
    >
    > diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c
    > index 24268882d355..a393584c7a73 100644
    > --- a/tools/perf/util/metricgroup.c
    > +++ b/tools/perf/util/metricgroup.c
    > @@ -1507,6 +1507,27 @@ static int parse_counter(const char *counter,
    > return 0;
    > }
    >
    > +static void metricgroup__free_event_info(struct list_head
    > + *event_info_list)
    > +{
    > + struct metricgroup__event_info *e, *tmp;
    > +
    > + list_for_each_entry_safe(e, tmp, event_info_list, nd) {
    > + list_del_init(&e->nd);
    > + free(e);
    > + }
    > +}
    > +
    > +static void metricgroup__free_pmu_info(struct list_head *pmu_info_list)
    > +{
    > + struct metricgroup__pmu_counters *p, *tmp;
    > +
    > + list_for_each_entry_safe(p, tmp, pmu_info_list, nd) {
    > + list_del_init(&p->nd);
    > + free(p);
    > + }
    > +}
    > +
    > static struct metricgroup__event_info *event_info__new(const char *name,
    > const char *pmu_name,
    > const char *counter,
    > @@ -1525,7 +1546,7 @@ static struct metricgroup__event_info *event_info__new(const char *name,
    >
    > e->name = name;
    > e->free_counter = free_counter;
    > - e->pmu_name = strdup(pmu_name);
    > + e->pmu_name = pmu_name;
    > if (free_counter) {
    > ret = set_counter_bitmap(0, e->counters);
    > if (ret)
    > @@ -1560,6 +1581,8 @@ static int metricgroup__add_metric_event_callback(const struct pmu_event *pe,
    > struct metricgroup__add_metric_event_data *d = data;
    >
    > if (!strcasecmp(pe->name, d->event_name)) {
    > + if (!pe->counter)
    > + return -EINVAL;
    > event = event_info__new(d->event_id, pe->pmu, pe->counter, /*free_counter=*/false);
    > if (!event)
    > return -ENOMEM;
    > @@ -1599,7 +1622,7 @@ static int get_metricgroup_events(const char *full_id,
    > .event_name = id,
    > .event_id = full_id,
    > };
    > - ret = pmu_events_table_for_each_event(table,
    > + ret = pmu_events_table__for_each_event(table, /*pmu=*/NULL,
    > metricgroup__add_metric_event_callback, &data);
    > }
    >
    > @@ -1608,6 +1631,57 @@ static int get_metricgroup_events(const char *full_id,
    > return ret;
    > }
    >
    > +static struct metricgroup__pmu_counters *pmu_layout__new(const struct pmu_layout *pl)
    > +{
    > + struct metricgroup__pmu_counters *l;
    > +
    > + l = zalloc(sizeof(*l));
    > +
    > + if (!l)
    > + return NULL;
    > +
    > + l->name = pl->pmu;
    > + l->size = pl->size;
    > + l->fixed_size = pl->fixed_size;
    > + pr_debug("create new pmu_layout: [pmu]=%s, [gp_size]=%ld, [fixed_size]=%ld\n",
    > + l->name, l->size, l->fixed_size);
    > + return l;
    > +}
    > +
    > +static int metricgroup__add_pmu_layout_callback(const struct pmu_layout *pl,
    > + void *data)
    > +{
    > + struct metricgroup__pmu_counters *pmu;
    > + struct list_head *d = data;
    > + int ret = 0;
    > +
    > + pmu = pmu_layout__new(pl);
    > + if (!pmu)
    > + return -ENOMEM;
    > + list_add(&pmu->nd, d);
    > + return ret;
    > +}
    > +
    > +/**
    > + * get_pmu_counter_layouts - Find counter info of the architecture from
    > + * the pmu_layouts table
    > + * @pmu_info_list: the list that the new counter info of a pmu is added to.
    > + * @table: pmu_layouts table that is searched for counter info.
    > + */
    > +static int get_pmu_counter_layouts(struct list_head *pmu_info_list,
    > + const struct pmu_layouts_table
    > + *table)
    > +{
    > + LIST_HEAD(list);
    > + int ret;
    > +
    > + ret = pmu_layouts_table__for_each_layout(table,
    > + metricgroup__add_pmu_layout_callback, &list);
    > +
    > + list_splice(&list, pmu_info_list);
    > + return ret;
    > +}
    > +
    > /**
    > * hw_aware_build_grouping - Build event groupings by reading counter
    > * requirement of the events and counter available on the system from
    > @@ -1626,6 +1700,7 @@ static int hw_aware_build_grouping(struct expr_parse_ctx *ctx __maybe_unused,
    > LIST_HEAD(event_info_list);
    > size_t bkt;
    > const struct pmu_events_table *etable = perf_pmu__find_events_table(NULL);
    > + const struct pmu_layouts_table *ltable = perf_pmu__find_layouts_table(NULL);
    >
    > #define RETURN_IF_NON_ZERO(x) do { if (x) return x; } while (0)
    > hashmap__for_each_entry(ctx->ids, cur, bkt) {
    > @@ -1635,9 +1710,13 @@ static int hw_aware_build_grouping(struct expr_parse_ctx *ctx __maybe_unused,
    >
    > ret = get_metricgroup_events(id, etable, &event_info_list);
    > if (ret)
    > - return ret;
    > + goto err_out;
    > }
    > + ret = get_pmu_counter_layouts(&pmu_info_list, ltable);
    >
    > +err_out:
    > + metricgroup__free_event_info(&event_info_list);
    > + metricgroup__free_pmu_info(&pmu_info_list);
    > return ret;
    > #undef RETURN_IF_NON_ZERO
    > }
    > diff --git a/tools/perf/util/metricgroup.h b/tools/perf/util/metricgroup.h
    > index 3704545c9a11..802ca15e7c6b 100644
    > --- a/tools/perf/util/metricgroup.h
    > +++ b/tools/perf/util/metricgroup.h
    > @@ -94,6 +94,21 @@ struct metricgroup__event_info {
    > DECLARE_BITMAP(counters, NR_COUNTERS);
    > };
    >
    > +/**
    > + * A node is the counter availability of a pmu.
    > + * This info is built up at the beginning from JSON file and
    > + * used as a reference in metric grouping process.
    > + */
    > +struct metricgroup__pmu_counters {
    > + struct list_head nd;
    > + /** The name of the pmu the event collected on. */
    > + const char *name;
    > + //DECLARE_BITMAP(counter_bits, NR_COUNTERS);

    nit: this can go.

    > + /** The number of gp counters in the pmu. */
    > + size_t size;
    > + size_t fixed_size;

    nit: same naming concern.

    Thanks,
    Ian

    > +};
    > +
    > /**
    > * Each group is one node in the group string list.
    > */
    > --
    > 2.39.3
    >

    \
     
     \ /
      Last update: 2024-05-27 14:32    [W:4.184 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site