Re: [PATCH v4 13/17] perf pmu-events: Don't assume pmu_event is an array

From: John Garry
Date: Fri Aug 05 2022 - 08:56:16 EST


On 04/08/2022 23:18, Ian Rogers wrote:
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.


I find it hard to follow the change from the description. The title is "Don't assume pmu_event is an array", but that is rightly what pmu_events_table_for_each_event() does.

If I check - for exmaple - pmu_add_cpu_aliases_map(), you just switch it over to using pmu_events_table_for_each_event(), which seems resonable. So it just seems here that we're refactoring the code, and not changing the nature of how we handle pmu_events *.


Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
---
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-events/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_tables[] = {
},
};
+int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_event_iter_fn fn,
+ void *data)
+{
+ for (const struct pmu_event *pe = &table[0];
+ pe->name || pe->metric_group || pe->metric_name;
+ pe++) {
+ int ret = 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 = NULL;
@@ -291,14 +305,10 @@ int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)
for (const struct pmu_events_map *tables = &pmu_events_map[0];
tables->table;
tables++) {
- for (const struct pmu_event *pe = &tables->table[0];
- pe->name || pe->metric_group || pe->metric_name;
- pe++) {
- int ret = fn(pe, &tables->table[0], data);
+ int ret = pmu_events_table_for_each_event(tables->table, fn, data);
- 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 = &pmu_sys_event_tables[0];
tables->name;
tables++) {
- for (const struct pmu_event *pe = &tables->table[0];
- pe->name || pe->metric_group || pe->metric_name;
- pe++) {
- int ret = fn(pe, &tables->table[0], data);
+ int ret = pmu_events_table_for_each_event(tables->table, fn, data);
- if (ret)
- return ret;
- }
+ if (ret)
+ return ret;
}
return 0;
}
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.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_tables[] = {
\t},
};
+int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_event_iter_fn fn,
+ void *data)

Again we seem to be just duplicating what is in empty-pmu-events.c - can we avoid this? another idea (apart from linking in other c files) is for empty-pmu-events.c to be generated from jevents.py (like how it was done for jevents.c)