Skip to content

Commit 660842e

Browse files
captain5050acmel
authored andcommitted
perf pmu-events: Don't assume pmu_event is an array
The 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 <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: James Clark <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: John Garry <[email protected]> Cc: Kan Liang <[email protected]> Cc: Leo Yan <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mike Leach <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ravi Bangoria <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Will Deacon <[email protected]> Cc: Xing Zhengjun <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 7ae5c03 commit 660842e

File tree

7 files changed

+313
-182
lines changed

7 files changed

+313
-182
lines changed

tools/perf/pmu-events/empty-pmu-events.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,20 @@ static const struct pmu_sys_events pmu_sys_event_tables[] = {
247247
},
248248
};
249249

250+
int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_event_iter_fn fn,
251+
void *data)
252+
{
253+
for (const struct pmu_event *pe = &table[0];
254+
pe->name || pe->metric_group || pe->metric_name;
255+
pe++) {
256+
int ret = fn(pe, table, data);
257+
258+
if (ret)
259+
return ret;
260+
}
261+
return 0;
262+
}
263+
250264
const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu)
251265
{
252266
const struct pmu_event *table = NULL;
@@ -291,14 +305,10 @@ int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data)
291305
for (const struct pmu_events_map *tables = &pmu_events_map[0];
292306
tables->table;
293307
tables++) {
294-
for (const struct pmu_event *pe = &tables->table[0];
295-
pe->name || pe->metric_group || pe->metric_name;
296-
pe++) {
297-
int ret = fn(pe, &tables->table[0], data);
308+
int ret = pmu_events_table_for_each_event(tables->table, fn, data);
298309

299-
if (ret)
300-
return ret;
301-
}
310+
if (ret)
311+
return ret;
302312
}
303313
return 0;
304314
}
@@ -319,14 +329,10 @@ int pmu_for_each_sys_event(pmu_event_iter_fn fn, void *data)
319329
for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
320330
tables->name;
321331
tables++) {
322-
for (const struct pmu_event *pe = &tables->table[0];
323-
pe->name || pe->metric_group || pe->metric_name;
324-
pe++) {
325-
int ret = fn(pe, &tables->table[0], data);
332+
int ret = pmu_events_table_for_each_event(tables->table, fn, data);
326333

327-
if (ret)
328-
return ret;
329-
}
334+
if (ret)
335+
return ret;
330336
}
331337
return 0;
332338
}

tools/perf/pmu-events/jevents.py

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,20 @@ def print_system_mapping_table() -> None:
410410
\t},
411411
};
412412
413+
int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_event_iter_fn fn,
414+
void *data)
415+
{
416+
for (const struct pmu_event *pe = &table[0];
417+
pe->name || pe->metric_group || pe->metric_name;
418+
pe++) {
419+
int ret = fn(pe, table, data);
420+
421+
if (ret)
422+
return ret;
423+
}
424+
return 0;
425+
}
426+
413427
const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu)
414428
{
415429
const struct pmu_event *table = NULL;
@@ -453,14 +467,10 @@ def print_system_mapping_table() -> None:
453467
for (const struct pmu_events_map *tables = &pmu_events_map[0];
454468
tables->table;
455469
tables++) {
456-
for (const struct pmu_event *pe = &tables->table[0];
457-
pe->name || pe->metric_group || pe->metric_name;
458-
pe++) {
459-
int ret = fn(pe, &tables->table[0], data);
470+
int ret = pmu_events_table_for_each_event(tables->table, fn, data);
460471
461-
if (ret)
462-
return ret;
463-
}
472+
if (ret)
473+
return ret;
464474
}
465475
return 0;
466476
}
@@ -481,14 +491,10 @@ def print_system_mapping_table() -> None:
481491
for (const struct pmu_sys_events *tables = &pmu_sys_event_tables[0];
482492
tables->name;
483493
tables++) {
484-
for (const struct pmu_event *pe = &tables->table[0];
485-
pe->name || pe->metric_group || pe->metric_name;
486-
pe++) {
487-
int ret = fn(pe, &tables->table[0], data);
494+
int ret = pmu_events_table_for_each_event(tables->table, fn, data);
488495
489-
if (ret)
490-
return ret;
491-
}
496+
if (ret)
497+
return ret;
492498
}
493499
return 0;
494500
}

tools/perf/pmu-events/pmu-events.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ typedef int (*pmu_event_iter_fn)(const struct pmu_event *pe,
3434
const struct pmu_event *table,
3535
void *data);
3636

37+
int pmu_events_table_for_each_event(const struct pmu_event *table, pmu_event_iter_fn fn,
38+
void *data);
39+
3740
const struct pmu_event *perf_pmu__find_table(struct perf_pmu *pmu);
3841
const struct pmu_event *find_core_events_table(const char *arch, const char *cpuid);
3942
int pmu_for_each_core_event(pmu_event_iter_fn fn, void *data);

tools/perf/tests/pmu-events.c

Lines changed: 78 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -423,84 +423,104 @@ static int compare_alias_to_test_event(struct perf_pmu_alias *alias,
423423
return 0;
424424
}
425425

426-
/* Verify generated events from pmu-events.c are as expected */
427-
static int test__pmu_event_table(struct test_suite *test __maybe_unused,
428-
int subtest __maybe_unused)
426+
static int test__pmu_event_table_core_callback(const struct pmu_event *pe,
427+
const struct pmu_event *table __maybe_unused,
428+
void *data)
429429
{
430-
const struct pmu_event *sys_event_tables = find_sys_events_table("pme_test_soc_sys");
431-
const struct pmu_event *table = find_core_events_table("testarch", "testcpu");
432-
int map_events = 0, expected_events;
430+
int *map_events = data;
431+
struct perf_pmu_test_event const **test_event_table;
432+
bool found = false;
433433

434-
/* ignore 3x sentinels */
435-
expected_events = ARRAY_SIZE(core_events) +
436-
ARRAY_SIZE(uncore_events) +
437-
ARRAY_SIZE(sys_events) - 3;
434+
if (!pe->name)
435+
return 0;
438436

439-
if (!table || !sys_event_tables)
440-
return -1;
437+
if (pe->pmu)
438+
test_event_table = &uncore_events[0];
439+
else
440+
test_event_table = &core_events[0];
441441

442-
for (; table->name; table++) {
443-
struct perf_pmu_test_event const **test_event_table;
444-
bool found = false;
442+
for (; *test_event_table; test_event_table++) {
443+
struct perf_pmu_test_event const *test_event = *test_event_table;
444+
struct pmu_event const *event = &test_event->event;
445445

446-
if (table->pmu)
447-
test_event_table = &uncore_events[0];
448-
else
449-
test_event_table = &core_events[0];
446+
if (strcmp(pe->name, event->name))
447+
continue;
448+
found = true;
449+
(*map_events)++;
450450

451-
for (; *test_event_table; test_event_table++) {
452-
struct perf_pmu_test_event const *test_event = *test_event_table;
453-
struct pmu_event const *event = &test_event->event;
451+
if (compare_pmu_events(pe, event))
452+
return -1;
454453

455-
if (strcmp(table->name, event->name))
456-
continue;
457-
found = true;
458-
map_events++;
454+
pr_debug("testing event table %s: pass\n", pe->name);
455+
}
456+
if (!found) {
457+
pr_err("testing event table: could not find event %s\n", pe->name);
458+
return -1;
459+
}
460+
return 0;
461+
}
459462

460-
if (compare_pmu_events(table, event))
461-
return -1;
463+
static int test__pmu_event_table_sys_callback(const struct pmu_event *pe,
464+
const struct pmu_event *table __maybe_unused,
465+
void *data)
466+
{
467+
int *map_events = data;
468+
struct perf_pmu_test_event const **test_event_table;
469+
bool found = false;
462470

463-
pr_debug("testing event table %s: pass\n", table->name);
464-
}
471+
test_event_table = &sys_events[0];
465472

466-
if (!found) {
467-
pr_err("testing event table: could not find event %s\n",
468-
table->name);
469-
return -1;
470-
}
471-
}
473+
for (; *test_event_table; test_event_table++) {
474+
struct perf_pmu_test_event const *test_event = *test_event_table;
475+
struct pmu_event const *event = &test_event->event;
472476

473-
for (table = sys_event_tables; table->name; table++) {
474-
struct perf_pmu_test_event const **test_event_table;
475-
bool found = false;
477+
if (strcmp(pe->name, event->name))
478+
continue;
479+
found = true;
480+
(*map_events)++;
476481

477-
test_event_table = &sys_events[0];
482+
if (compare_pmu_events(pe, event))
483+
return TEST_FAIL;
478484

479-
for (; *test_event_table; test_event_table++) {
480-
struct perf_pmu_test_event const *test_event = *test_event_table;
481-
struct pmu_event const *event = &test_event->event;
485+
pr_debug("testing sys event table %s: pass\n", pe->name);
486+
}
487+
if (!found) {
488+
pr_debug("testing sys event table: could not find event %s\n", pe->name);
489+
return TEST_FAIL;
490+
}
491+
return TEST_OK;
492+
}
482493

483-
if (strcmp(table->name, event->name))
484-
continue;
485-
found = true;
486-
map_events++;
494+
/* Verify generated events from pmu-events.c are as expected */
495+
static int test__pmu_event_table(struct test_suite *test __maybe_unused,
496+
int subtest __maybe_unused)
497+
{
498+
const struct pmu_event *sys_event_table = find_sys_events_table("pme_test_soc_sys");
499+
const struct pmu_event *table = find_core_events_table("testarch", "testcpu");
500+
int map_events = 0, expected_events, err;
487501

488-
if (compare_pmu_events(table, event))
489-
return -1;
502+
/* ignore 3x sentinels */
503+
expected_events = ARRAY_SIZE(core_events) +
504+
ARRAY_SIZE(uncore_events) +
505+
ARRAY_SIZE(sys_events) - 3;
490506

491-
pr_debug("testing sys event table %s: pass\n", table->name);
492-
}
493-
if (!found) {
494-
pr_debug("testing event table: could not find event %s\n",
495-
table->name);
496-
return -1;
497-
}
498-
}
507+
if (!table || !sys_event_table)
508+
return -1;
509+
510+
err = pmu_events_table_for_each_event(table, test__pmu_event_table_core_callback,
511+
&map_events);
512+
if (err)
513+
return err;
514+
515+
err = pmu_events_table_for_each_event(sys_event_table, test__pmu_event_table_sys_callback,
516+
&map_events);
517+
if (err)
518+
return err;
499519

500520
if (map_events != expected_events) {
501521
pr_err("testing event table: found %d, but expected %d\n",
502522
map_events, expected_events);
503-
return -1;
523+
return TEST_FAIL;
504524
}
505525

506526
return 0;

0 commit comments

Comments
 (0)