From nobody Sat Apr 11 22:47:45 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7CF19C25B06 for ; Thu, 4 Aug 2022 22:20:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240063AbiHDWUK (ORCPT ); Thu, 4 Aug 2022 18:20:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48118 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240140AbiHDWTP (ORCPT ); Thu, 4 Aug 2022 18:19:15 -0400 Received: from mail-yw1-x1149.google.com (mail-yw1-x1149.google.com [IPv6:2607:f8b0:4864:20::1149]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2083672EC4 for ; Thu, 4 Aug 2022 15:18:58 -0700 (PDT) Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-31f58599ad3so6981107b3.20 for ; Thu, 04 Aug 2022 15:18:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc; bh=buQfuAYV6srkjKdCo6UV3mNN0x2luqHdC6z6WdoFZhs=; b=fWZFlrzx8vxc9xQrM6ZtLHwUX0ccBcMSdMNR2ggkfsWN1NIRDLHmIVq+oqFH0Y/CUO lJZJ+W7yxQ7gg2M/6HcroQObaGZb25Jk35/0V9UhvviPqUIxe/t3jcBsbo3a3SsSRdLC a3pU7Ov+3kYr78k9zZXhi2QkOfazVtTpp2wocSbHF0iM6NYqBtVdeF1hc80hddTiojFe zJJXAiCddAu7I6u9zJOAvFIP5QpMB15gcOd7neSKzEdQm1ksrDExXffqpwtz7Qi6j2tJ tibkByAi8ySLhG5FU1c0+gDUxsCaun7QM6CAXNYtQgdAtOpUOXqDJNGErSnlVP/fYmJS 5jIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc; bh=buQfuAYV6srkjKdCo6UV3mNN0x2luqHdC6z6WdoFZhs=; b=Up45kgeFMeZXhXPH0mCZOc6XKBtWn58bCffAhI3ogDV/uJ4LLnxX85b68//eUAGSb+ neLf89Y1K3BlgZiUmGHF0QP3ewxmBmyMZ5prIG2vIwzoDVoRBixgeIEBUSrFpXXQ7SSh TUBQY5OjUJuUCJKZmMPeeZ5ktX2QQClLh4wYMOhga/LETLqTxVuRn4DfG7o8OY274j8C 96+EwPOMfglcwjlUgSu8KvDUqVZk73j90p+KlrDXwEqOJWKPcc9uiI1S7b3W9BNkRCPw AhlXWLui7ISfxlRRIpcg5Bwa/+6BP6s7XRrNkXt3tcAK6g+CeI7Yxx1bFFRH0FW9e5ge 3z1A== X-Gm-Message-State: ACgBeo0zm4t8+Z68op7oWRqBsJziaCYiTpZh13/EKdVZX8dSiDZFA2Oz EJ7qcGorUna0k6Mm35awy5vJ5o2oHld+ X-Google-Smtp-Source: AA6agR5czhZhLekpql59UmyRwRG1k+V/2q4eEHoeBa5PmW/UqMA35yUxhbRl7c0ELA11mbWTDuI1s1HXdBP6 X-Received: from irogers.svl.corp.google.com ([2620:15c:2d4:203:f5e1:5bc5:7dab:2b7c]) (user=irogers job=sendgmr) by 2002:a25:ca58:0:b0:677:3543:ca4a with SMTP id a85-20020a25ca58000000b006773543ca4amr3250822ybg.291.1659651537703; Thu, 04 Aug 2022 15:18:57 -0700 (PDT) Date: Thu, 4 Aug 2022 15:18:12 -0700 In-Reply-To: <20220804221816.1802790-1-irogers@google.com> Message-Id: <20220804221816.1802790-14-irogers@google.com> Mime-Version: 1.0 References: <20220804221816.1802790-1-irogers@google.com> X-Mailer: git-send-email 2.37.1.559.g78731f0fdb-goog Subject: [PATCH v4 13/17] perf pmu-events: Don't assume pmu_event is an array From: Ian Rogers To: John Garry , Will Deacon , James Clark , Mike Leach , Leo Yan , Peter Zijlstra , Ingo Molnar , Arnaldo Carvalho de Melo , Mark Rutland , Alexander Shishkin , Jiri Olsa , Namhyung Kim , Andi Kleen , Zhengjun Xing , Ravi Bangoria , Kan Liang , Adrian Hunter , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-perf-users@vger.kernel.org Cc: Stephane Eranian , Ian Rogers Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Current code assumes that a struct pmu_event can be iterated over forward until a NULL pmu_event is encountered. This makes it difficult to refactor pmu_event. Add a loop function taking a callback function that's passed the struct pmu_event. This way the pmu_event is only needed for one element and not an entire array. Switch existing code iterating over the pmu_event arrays to use the new loop function pmu_events_table_for_each_event. Signed-off-by: Ian Rogers --- tools/perf/pmu-events/empty-pmu-events.c | 34 +++-- tools/perf/pmu-events/jevents.py | 34 +++-- tools/perf/pmu-events/pmu-events.h | 3 + tools/perf/tests/pmu-events.c | 136 +++++++++-------- tools/perf/util/metricgroup.c | 181 ++++++++++++++++------- tools/perf/util/pmu.c | 65 ++++---- tools/perf/util/s390-sample-raw.c | 42 ++++-- 7 files changed, 313 insertions(+), 182 deletions(-) diff --git a/tools/perf/pmu-events/empty-pmu-events.c b/tools/perf/pmu-even= ts/empty-pmu-events.c index 028f44efe48d..bee1967baa2b 100644 --- a/tools/perf/pmu-events/empty-pmu-events.c +++ b/tools/perf/pmu-events/empty-pmu-events.c @@ -247,6 +247,20 @@ static const struct pmu_sys_events pmu_sys_event_table= s[] =3D { }, }; =20 +int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_eve= nt_iter_fn fn, + void *data) +{ + for (const struct pmu_event *pe =3D &table[0]; + pe->name || pe->metric_group || pe->metric_name; + pe++) { + int ret =3D fn(pe, table, data); + + if (ret) + return ret; + } + return 0; +} + const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) { const struct pmu_event *table =3D NULL; @@ -291,14 +305,10 @@ int pmu_for_each_core_event(pmu_event_iter_fn fn, voi= d *data) for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; tables->table; tables++) { - for (const struct pmu_event *pe =3D &tables->table[0]; - pe->name || pe->metric_group || pe->metric_name; - pe++) { - int ret =3D fn(pe, &tables->table[0], data); + int ret =3D pmu_events_table_for_each_event(tables->table, fn, data); =20 - if (ret) - return ret; - } + if (ret) + return ret; } return 0; } @@ -319,14 +329,10 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void= *data) for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables[0]; tables->name; tables++) { - for (const struct pmu_event *pe =3D &tables->table[0]; - pe->name || pe->metric_group || pe->metric_name; - pe++) { - int ret =3D fn(pe, &tables->table[0], data); + int ret =3D pmu_events_table_for_each_event(tables->table, fn, data); =20 - if (ret) - return ret; - } + if (ret) + return ret; } return 0; } diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jeven= ts.py index e976c5e8e80b..365c960202b0 100755 --- a/tools/perf/pmu-events/jevents.py +++ b/tools/perf/pmu-events/jevents.py @@ -409,6 +409,20 @@ static const struct pmu_sys_events pmu_sys_event_table= s[] =3D { \t}, }; =20 +int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_eve= nt_iter_fn fn, + void *data) +{ + for (const struct pmu_event *pe =3D &table[0]; + pe->name || pe->metric_group || pe->metric_name; + pe++) { + int ret =3D fn(pe, table, data); + + if (ret) + return ret; + } + return 0; +} + const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu) { const struct pmu_event *table =3D NULL; @@ -452,14 +466,10 @@ int pmu_for_each_core_event(pmu_event_iter_fn fn, voi= d *data) for (const struct pmu_events_map *tables =3D &pmu_events_map[0]; tables->table; tables++) { - for (const struct pmu_event *pe =3D &tables->table[0]; - pe->name || pe->metric_group || pe->metric_name; - pe++) { - int ret =3D fn(pe, &tables->table[0], data); + int ret =3D pmu_events_table_for_each_event(tables->table,= fn, data); =20 - if (ret) - return ret; - } + if (ret) + return ret; } return 0; } @@ -480,14 +490,10 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void= *data) for (const struct pmu_sys_events *tables =3D &pmu_sys_event_tables= [0]; tables->name; tables++) { - for (const struct pmu_event *pe =3D &tables->table[0]; - pe->name || pe->metric_group || pe->metric_name; - pe++) { - int ret =3D fn(pe, &tables->table[0], data); + int ret =3D pmu_events_table_for_each_event(tables->table,= fn, data); =20 - if (ret) - return ret; - } + if (ret) + return ret; } return 0; } diff --git a/tools/perf/pmu-events/pmu-events.h b/tools/perf/pmu-events/pmu= -events.h index 485e730f9922..70672842f77f 100644 --- a/tools/perf/pmu-events/pmu-events.h +++ b/tools/perf/pmu-events/pmu-events.h @@ -34,6 +34,9 @@ typedef int (*pmu_event_iter_fn)(const struct pmu_event *= pe, const struct pmu_event *table, void *data); =20 +int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_eve= nt_iter_fn fn, + void *data); + const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu); const struct pmu_event *find_core_events_table(const char *arch, const cha= r *cpuid); int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data); diff --git a/tools/perf/tests/pmu-events.c b/tools/perf/tests/pmu-events.c index e8df6bc26ebd..1c3479e5890e 100644 --- a/tools/perf/tests/pmu-events.c +++ b/tools/perf/tests/pmu-events.c @@ -423,84 +423,104 @@ static int compare_alias_to_test_event(struct perf_p= mu_alias *alias, return 0; } =20 -/* Verify generated events from pmu-events.c are as expected */ -static int test__pmu_event_table(struct test_suite *test __maybe_unused, - int subtest __maybe_unused) +static int test__pmu_event_table_core_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *data) { - const struct pmu_event *sys_event_tables =3D find_sys_events_table("pme_t= est_soc_sys"); - const struct pmu_event *table =3D find_core_events_table("testarch", "tes= tcpu"); - int map_events =3D 0, expected_events; + int *map_events =3D data; + struct perf_pmu_test_event const **test_event_table; + bool found =3D false; =20 - /* ignore 3x sentinels */ - expected_events =3D ARRAY_SIZE(core_events) + - ARRAY_SIZE(uncore_events) + - ARRAY_SIZE(sys_events) - 3; + if (!pe->name) + return 0; =20 - if (!table || !sys_event_tables) - return -1; + if (pe->pmu) + test_event_table =3D &uncore_events[0]; + else + test_event_table =3D &core_events[0]; =20 - for (; table->name; table++) { - struct perf_pmu_test_event const **test_event_table; - bool found =3D false; + for (; *test_event_table; test_event_table++) { + struct perf_pmu_test_event const *test_event =3D *test_event_table; + struct pmu_event const *event =3D &test_event->event; =20 - if (table->pmu) - test_event_table =3D &uncore_events[0]; - else - test_event_table =3D &core_events[0]; + if (strcmp(pe->name, event->name)) + continue; + found =3D true; + (*map_events)++; =20 - for (; *test_event_table; test_event_table++) { - struct perf_pmu_test_event const *test_event =3D *test_event_table; - struct pmu_event const *event =3D &test_event->event; + if (compare_pmu_events(pe, event)) + return -1; =20 - if (strcmp(table->name, event->name)) - continue; - found =3D true; - map_events++; + pr_debug("testing event table %s: pass\n", pe->name); + } + if (!found) { + pr_err("testing event table: could not find event %s\n", pe->name); + return -1; + } + return 0; +} =20 - if (compare_pmu_events(table, event)) - return -1; +static int test__pmu_event_table_sys_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *data) +{ + int *map_events =3D data; + struct perf_pmu_test_event const **test_event_table; + bool found =3D false; =20 - pr_debug("testing event table %s: pass\n", table->name); - } + test_event_table =3D &sys_events[0]; =20 - if (!found) { - pr_err("testing event table: could not find event %s\n", - table->name); - return -1; - } - } + for (; *test_event_table; test_event_table++) { + struct perf_pmu_test_event const *test_event =3D *test_event_table; + struct pmu_event const *event =3D &test_event->event; =20 - for (table =3D sys_event_tables; table->name; table++) { - struct perf_pmu_test_event const **test_event_table; - bool found =3D false; + if (strcmp(pe->name, event->name)) + continue; + found =3D true; + (*map_events)++; =20 - test_event_table =3D &sys_events[0]; + if (compare_pmu_events(pe, event)) + return TEST_FAIL; =20 - for (; *test_event_table; test_event_table++) { - struct perf_pmu_test_event const *test_event =3D *test_event_table; - struct pmu_event const *event =3D &test_event->event; + pr_debug("testing sys event table %s: pass\n", pe->name); + } + if (!found) { + pr_debug("testing sys event table: could not find event %s\n", pe->name); + return TEST_FAIL; + } + return TEST_OK; +} =20 - if (strcmp(table->name, event->name)) - continue; - found =3D true; - map_events++; +/* Verify generated events from pmu-events.c are as expected */ +static int test__pmu_event_table(struct test_suite *test __maybe_unused, + int subtest __maybe_unused) +{ + const struct pmu_event *sys_event_table =3D find_sys_events_table("pme_te= st_soc_sys"); + const struct pmu_event *table =3D find_core_events_table("testarch", "tes= tcpu"); + int map_events =3D 0, expected_events, err; =20 - if (compare_pmu_events(table, event)) - return -1; + /* ignore 3x sentinels */ + expected_events =3D ARRAY_SIZE(core_events) + + ARRAY_SIZE(uncore_events) + + ARRAY_SIZE(sys_events) - 3; =20 - pr_debug("testing sys event table %s: pass\n", table->name); - } - if (!found) { - pr_debug("testing event table: could not find event %s\n", - table->name); - return -1; - } - } + if (!table || !sys_event_table) + return -1; + + err =3D pmu_events_table_for_each_event(table, test__pmu_event_table_core= _callback, + &map_events); + if (err) + return err; + + err =3D pmu_events_table_for_each_event(sys_event_table, test__pmu_event_= table_sys_callback, + &map_events); + if (err) + return err; =20 if (map_events !=3D expected_events) { pr_err("testing event table: found %d, but expected %d\n", map_events, expected_events); - return -1; + return TEST_FAIL; } =20 return 0; diff --git a/tools/perf/util/metricgroup.c b/tools/perf/util/metricgroup.c index 680f7c63838d..f702b73a7609 100644 --- a/tools/perf/util/metricgroup.c +++ b/tools/perf/util/metricgroup.c @@ -538,12 +538,40 @@ static int metricgroup__print_sys_event_iter(const st= ruct pmu_event *pe, d->details, d->groups, d->metriclist); } =20 +struct metricgroup_print_data { + const char *pmu_name; + struct strlist *metriclist; + char *filter; + struct rblist *groups; + bool metricgroups; + bool raw; + bool details; +}; + +static int metricgroup__print_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *vdata) +{ + struct metricgroup_print_data *data =3D vdata; + + if (!pe->metric_expr) + return 0; + + if (data->pmu_name && perf_pmu__is_hybrid(pe->pmu) && strcmp(data->pmu_na= me, pe->pmu)) + return 0; + + return metricgroup__print_pmu_event(pe, data->metricgroups, data->filter, + data->raw, data->details, data->groups, + data->metriclist); +} + void metricgroup__print(bool metrics, bool metricgroups, char *filter, bool raw, bool details, const char *pmu_name) { struct rblist groups; struct rb_node *node, *next; struct strlist *metriclist =3D NULL; + const struct pmu_event *table; =20 if (!metricgroups) { metriclist =3D strlist__new(NULL, NULL); @@ -555,22 +583,22 @@ void metricgroup__print(bool metrics, bool metricgrou= ps, char *filter, groups.node_new =3D mep_new; groups.node_cmp =3D mep_cmp; groups.node_delete =3D mep_delete; - for (const struct pmu_event *pe =3D pmu_events_map__find(); pe; pe++) { + table =3D pmu_events_map__find(); + if (table) { + struct metricgroup_print_data data =3D { + .pmu_name =3D pmu_name, + .metriclist =3D metriclist, + .metricgroups =3D metricgroups, + .filter =3D filter, + .raw =3D raw, + .details =3D details, + .groups =3D &groups, + }; =20 - if (!pe->name && !pe->metric_group && !pe->metric_name) - break; - if (!pe->metric_expr) - continue; - if (pmu_name && perf_pmu__is_hybrid(pe->pmu) && - strcmp(pmu_name, pe->pmu)) { - continue; - } - if (metricgroup__print_pmu_event(pe, metricgroups, filter, - raw, details, &groups, - metriclist) < 0) - return; + pmu_events_table_for_each_event(table, + metricgroup__print_callback, + &data); } - { struct metricgroup_iter_data data =3D { .fn =3D metricgroup__print_sys_event_iter, @@ -1043,30 +1071,35 @@ static int __add_metric(struct list_head *metric_li= st, return ret; } =20 -#define table_for_each_event(__pe, __idx, __table) \ - if (__table) \ - for (__idx =3D 0, __pe =3D &__table[__idx]; \ - __pe->name || __pe->metric_group || __pe->metric_name; \ - __pe =3D &__table[++__idx]) +struct metricgroup__find_metric_data { + const char *metric; + const struct pmu_event *pe; +}; + +static int metricgroup__find_metric_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *vdata) +{ + struct metricgroup__find_metric_data *data =3D vdata; + + if (!match_metric(pe->metric_name, data->metric)) + return 0; =20 -#define table_for_each_metric(__pe, __idx, __table, __metric) \ - table_for_each_event(__pe, __idx, __table) \ - if (__pe->metric_expr && \ - (match_metric(__pe->metric_group, __metric) || \ - match_metric(__pe->metric_name, __metric))) + data->pe =3D pe; + return -1; +} =20 const struct pmu_event *metricgroup__find_metric(const char *metric, const struct pmu_event *table) { - const struct pmu_event *pe; - int i; + struct metricgroup__find_metric_data data =3D { + .metric =3D metric, + .pe =3D NULL, + }; =20 - table_for_each_event(pe, i, table) { - if (match_metric(pe->metric_name, metric)) - return pe; - } + pmu_events_table_for_each_event(table, metricgroup__find_metric_callback,= &data); =20 - return NULL; + return data.pe; } =20 static int add_metric(struct list_head *metric_list, @@ -1151,6 +1184,33 @@ static int metric_list_cmp(void *priv __maybe_unused= , const struct list_head *l, return right_count - left_count; } =20 +struct metricgroup__add_metric_data { + struct list_head *list; + const char *metric_name; + const char *modifier; + bool metric_no_group; + bool has_match; +}; + +static int metricgroup__add_metric_callback(const struct pmu_event *pe, + const struct pmu_event *table, + void *vdata) +{ + struct metricgroup__add_metric_data *data =3D vdata; + int ret =3D 0; + + if (pe->metric_expr && + (match_metric(pe->metric_group, data->metric_name) || + match_metric(pe->metric_name, data->metric_name))) { + + data->has_match =3D true; + ret =3D add_metric(data->list, pe, data->modifier, data->metric_no_group, + /*root_metric=3D*/NULL, + /*visited_metrics=3D*/NULL, table); + } + return ret; +} + /** * metricgroup__add_metric - Find and add a metric, or a metric group. * @metric_name: The name of the metric or metric group. For example, "IPC" @@ -1169,24 +1229,29 @@ static int metricgroup__add_metric(const char *metr= ic_name, const char *modifier struct list_head *metric_list, const struct pmu_event *table) { - const struct pmu_event *pe; LIST_HEAD(list); - int i, ret; + int ret; bool has_match =3D false; =20 - /* - * Iterate over all metrics seeing if metric matches either the name or - * group. When it does add the metric to the list. - */ - table_for_each_metric(pe, i, table, metric_name) { - has_match =3D true; - ret =3D add_metric(&list, pe, modifier, metric_no_group, - /*root_metric=3D*/NULL, - /*visited_metrics=3D*/NULL, table); + { + struct metricgroup__add_metric_data data =3D { + .list =3D &list, + .metric_name =3D metric_name, + .modifier =3D modifier, + .metric_no_group =3D metric_no_group, + .has_match =3D false, + }; + /* + * Iterate over all metrics seeing if metric matches either the + * name or group. When it does add the metric to the list. + */ + ret =3D pmu_events_table_for_each_event(table, metricgroup__add_metric_c= allback, + &data); if (ret) goto out; - } =20 + has_match =3D data.has_match; + } { struct metricgroup_iter_data data =3D { .fn =3D metricgroup__add_metric_sys_event_iter, @@ -1602,26 +1667,30 @@ int metricgroup__parse_groups_test(struct evlist *e= vlist, metric_no_merge, &perf_pmu__fake, metric_events, table); } =20 +static int metricgroup__has_metric_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *vdata) +{ + const char *metric =3D vdata; + + if (!pe->metric_expr) + return 0; + + if (match_metric(pe->metric_name, metric)) + return 1; + + return 0; +} + bool metricgroup__has_metric(const char *metric) { const struct pmu_event *table =3D pmu_events_map__find(); - const struct pmu_event *pe; - int i; =20 if (!table) return false; =20 - for (i =3D 0; ; i++) { - pe =3D &table[i]; - - if (!pe->name && !pe->metric_group && !pe->metric_name) - break; - if (!pe->metric_expr) - continue; - if (match_metric(pe->metric_name, metric)) - return true; - } - return false; + return pmu_events_table_for_each_event(table, metricgroup__has_metric_cal= lback, + (void *)metric) ? true : false; } =20 int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *= cgrp, diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 5bb03d4e52a3..ab94d672d7bf 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -791,6 +791,36 @@ bool pmu_uncore_alias_match(const char *pmu_name, cons= t char *name) return res; } =20 +struct pmu_add_cpu_aliases_map_data { + struct list_head *head; + const char *name; + const char *cpu_name; + struct perf_pmu *pmu; +}; + +static int pmu_add_cpu_aliases_map_callback(const struct pmu_event *pe, + const struct pmu_event *table __maybe_unused, + void *vdata) +{ + struct pmu_add_cpu_aliases_map_data *data =3D vdata; + const char *pname =3D pe->pmu ? pe->pmu : data->cpu_name; + + if (!pe->name) + return 0; + + if (data->pmu->is_uncore && pmu_uncore_alias_match(pname, data->name)) + goto new_alias; + + if (strcmp(pname, data->name)) + return 0; + +new_alias: + /* need type casts to override 'const' */ + __perf_pmu__new_alias(data->head, NULL, (char *)pe->name, (char *)pe->des= c, + (char *)pe->event, pe); + return 0; +} + /* * From the pmu_events_map, find the table of PMU events that corresponds * to the current running CPU. Then, add all PMU events from that table @@ -799,35 +829,14 @@ bool pmu_uncore_alias_match(const char *pmu_name, con= st char *name) void pmu_add_cpu_aliases_map(struct list_head *head, struct perf_pmu *pmu, const struct pmu_event *table) { - int i; - const char *name =3D pmu->name; - /* - * Found a matching PMU events table. Create aliases - */ - i =3D 0; - while (1) { - const char *cpu_name =3D is_arm_pmu_core(name) ? name : "cpu"; - const struct pmu_event *pe =3D &table[i++]; - const char *pname =3D pe->pmu ? pe->pmu : cpu_name; - - if (!pe->name) { - if (pe->metric_group || pe->metric_name) - continue; - break; - } - - if (pmu->is_uncore && pmu_uncore_alias_match(pname, name)) - goto new_alias; - - if (strcmp(pname, name)) - continue; + struct pmu_add_cpu_aliases_map_data data =3D { + .head =3D head, + .name =3D pmu->name, + .cpu_name =3D is_arm_pmu_core(pmu->name) ? pmu->name : "cpu", + .pmu =3D pmu, + }; =20 -new_alias: - /* need type casts to override 'const' */ - __perf_pmu__new_alias(head, NULL, (char *)pe->name, - (char *)pe->desc, (char *)pe->event, - pe); - } + pmu_events_table_for_each_event(table, pmu_add_cpu_aliases_map_callback, = &data); } =20 static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *p= mu) diff --git a/tools/perf/util/s390-sample-raw.c b/tools/perf/util/s390-sampl= e-raw.c index 1ecb718fc0eb..b1c052c176bb 100644 --- a/tools/perf/util/s390-sample-raw.c +++ b/tools/perf/util/s390-sample-raw.c @@ -129,6 +129,28 @@ static int get_counterset_start(int setnr) } } =20 +struct get_counter_name_data { + int wanted; + const char *result; +}; + +static int get_counter_name_callback(const struct pmu_event *evp, + const struct pmu_event *table __maybe_unused, + void *vdata) +{ + struct get_counter_name_data *data =3D vdata; + int rc, event_nr; + + if (evp->name =3D=3D NULL || evp->event =3D=3D NULL) + return 0; + rc =3D sscanf(evp->event, "event=3D%x", &event_nr); + if (rc =3D=3D 1 && event_nr =3D=3D data->wanted) { + data->result =3D evp->name; + return 1; /* Terminate the search. */ + } + return 0; +} + /* Scan the PMU table and extract the logical name of a counter from the * PMU events table. Input is the counter set and counter number with in t= he * set. Construct the event number and use this as key. If they match retu= rn @@ -137,20 +159,16 @@ static int get_counterset_start(int setnr) */ static const char *get_counter_name(int set, int nr, const struct pmu_even= t *table) { - int rc, event_nr, wanted =3D get_counterset_start(set) + nr; + struct get_counter_name_data data =3D { + .wanted =3D get_counterset_start(set) + nr, + .result =3D NULL, + }; =20 - if (table) { - const struct pmu_event *evp =3D table; + if (!table) + return NULL; =20 - for (; evp->name || evp->event || evp->desc; ++evp) { - if (evp->name =3D=3D NULL || evp->event =3D=3D NULL) - continue; - rc =3D sscanf(evp->event, "event=3D%x", &event_nr); - if (rc =3D=3D 1 && event_nr =3D=3D wanted) - return evp->name; - } - } - return NULL; + pmu_events_table_for_each_event(table, get_counter_name_callback, &data); + return data.result; } =20 static void s390_cpumcfdg_dump(struct perf_sample *sample) --=20 2.37.1.559.g78731f0fdb-goog