Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

perf metricgroup: Factor out for-each function and move out printing

Factor metricgroup__for_each_metric into its own function handling
regular and sys metrics. Make the metric adding and printing code use
it, move the printing code into print-events files.

Signed-off-by: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20250710235126.1086011-6-irogers@google.com
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Ian Rogers and committed by
Namhyung Kim
cb336b6a 8c75dc74

+165 -214
+28 -213
tools/perf/util/metricgroup.c
··· 384 384 match_metric_or_groups(pm->metric_name, metric_or_groups); 385 385 } 386 386 387 - /** struct mep - RB-tree node for building printing information. */ 388 - struct mep { 389 - /** nd - RB-tree element. */ 390 - struct rb_node nd; 391 - /** @metric_group: Owned metric group name, separated others with ';'. */ 392 - char *metric_group; 393 - const char *metric_name; 394 - const char *metric_desc; 395 - const char *metric_long_desc; 396 - const char *metric_expr; 397 - const char *metric_threshold; 398 - const char *metric_unit; 399 - const char *pmu_name; 400 - }; 401 - 402 - static int mep_cmp(struct rb_node *rb_node, const void *entry) 403 - { 404 - struct mep *a = container_of(rb_node, struct mep, nd); 405 - struct mep *b = (struct mep *)entry; 406 - int ret; 407 - 408 - ret = strcmp(a->metric_group, b->metric_group); 409 - if (ret) 410 - return ret; 411 - 412 - return strcmp(a->metric_name, b->metric_name); 413 - } 414 - 415 - static struct rb_node *mep_new(struct rblist *rl __maybe_unused, const void *entry) 416 - { 417 - struct mep *me = malloc(sizeof(struct mep)); 418 - 419 - if (!me) 420 - return NULL; 421 - 422 - memcpy(me, entry, sizeof(struct mep)); 423 - return &me->nd; 424 - } 425 - 426 - static void mep_delete(struct rblist *rl __maybe_unused, 427 - struct rb_node *nd) 428 - { 429 - struct mep *me = container_of(nd, struct mep, nd); 430 - 431 - zfree(&me->metric_group); 432 - free(me); 433 - } 434 - 435 - static struct mep *mep_lookup(struct rblist *groups, const char *metric_group, 436 - const char *metric_name) 437 - { 438 - struct rb_node *nd; 439 - struct mep me = { 440 - .metric_group = strdup(metric_group), 441 - .metric_name = metric_name, 442 - }; 443 - nd = rblist__find(groups, &me); 444 - if (nd) { 445 - free(me.metric_group); 446 - return container_of(nd, struct mep, nd); 447 - } 448 - rblist__add_node(groups, &me); 449 - nd = rblist__find(groups, &me); 450 - if (nd) 451 - return container_of(nd, struct mep, nd); 452 - return NULL; 453 - } 454 - 455 - static int metricgroup__add_to_mep_groups(const struct pmu_metric *pm, 456 - struct rblist *groups) 457 - { 458 - const char *g; 459 - char *omg, *mg; 460 - 461 - mg = strdup(pm->metric_group ?: pm->metric_name); 462 - if (!mg) 463 - return -ENOMEM; 464 - omg = mg; 465 - while ((g = strsep(&mg, ";")) != NULL) { 466 - struct mep *me; 467 - 468 - g = skip_spaces(g); 469 - if (strlen(g)) 470 - me = mep_lookup(groups, g, pm->metric_name); 471 - else 472 - me = mep_lookup(groups, pm->metric_name, pm->metric_name); 473 - 474 - if (me) { 475 - me->metric_desc = pm->desc; 476 - me->metric_long_desc = pm->long_desc; 477 - me->metric_expr = pm->metric_expr; 478 - me->metric_threshold = pm->metric_threshold; 479 - me->metric_unit = pm->unit; 480 - me->pmu_name = pm->pmu; 481 - } 482 - } 483 - free(omg); 484 - 485 - return 0; 486 - } 487 - 488 387 struct metricgroup_iter_data { 489 388 pmu_metric_iter_fn fn; 490 389 void *data; ··· 409 510 return 0; 410 511 } 411 512 412 - static int metricgroup__add_to_mep_groups_callback(const struct pmu_metric *pm, 413 - const struct pmu_metrics_table *table __maybe_unused, 414 - void *vdata) 513 + int metricgroup__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn, 514 + void *data) 415 515 { 416 - struct rblist *groups = vdata; 516 + struct metricgroup_iter_data sys_data = { 517 + .fn = fn, 518 + .data = data, 519 + }; 417 520 418 - return metricgroup__add_to_mep_groups(pm, groups); 419 - } 420 - 421 - void metricgroup__print(const struct print_callbacks *print_cb, void *print_state) 422 - { 423 - struct rblist groups; 424 - const struct pmu_metrics_table *table; 425 - struct rb_node *node, *next; 426 - 427 - rblist__init(&groups); 428 - groups.node_new = mep_new; 429 - groups.node_cmp = mep_cmp; 430 - groups.node_delete = mep_delete; 431 - table = pmu_metrics_table__find(); 432 521 if (table) { 433 - pmu_metrics_table__for_each_metric(table, 434 - metricgroup__add_to_mep_groups_callback, 435 - &groups); 436 - } 437 - { 438 - struct metricgroup_iter_data data = { 439 - .fn = metricgroup__add_to_mep_groups_callback, 440 - .data = &groups, 441 - }; 442 - pmu_for_each_sys_metric(metricgroup__sys_event_iter, &data); 522 + int ret = pmu_metrics_table__for_each_metric(table, fn, data); 523 + 524 + if (ret) 525 + return ret; 443 526 } 444 527 445 - for (node = rb_first_cached(&groups.entries); node; node = next) { 446 - struct mep *me = container_of(node, struct mep, nd); 447 - 448 - print_cb->print_metric(print_state, 449 - me->metric_group, 450 - me->metric_name, 451 - me->metric_desc, 452 - me->metric_long_desc, 453 - me->metric_expr, 454 - me->metric_threshold, 455 - me->metric_unit, 456 - me->pmu_name); 457 - next = rb_next(node); 458 - rblist__remove_node(&groups, node); 459 - } 528 + return pmu_for_each_sys_metric(metricgroup__sys_event_iter, &sys_data); 460 529 } 461 530 462 531 static const char *code_characters = ",-=@"; ··· 957 1090 return ret; 958 1091 } 959 1092 960 - static int metricgroup__add_metric_sys_event_iter(const struct pmu_metric *pm, 961 - const struct pmu_metrics_table *table __maybe_unused, 962 - void *data) 963 - { 964 - struct metricgroup_add_iter_data *d = data; 965 - int ret; 966 - 967 - if (!match_pm_metric_or_groups(pm, d->pmu, d->metric_name)) 968 - return 0; 969 - 970 - ret = add_metric(d->metric_list, pm, d->modifier, d->metric_no_group, 971 - d->metric_no_threshold, d->user_requested_cpu_list, 972 - d->system_wide, d->root_metric, d->visited, d->table); 973 - if (ret) 974 - goto out; 975 - 976 - *(d->has_match) = true; 977 - 978 - out: 979 - *(d->ret) = ret; 980 - return ret; 981 - } 982 - 983 1093 /** 984 1094 * metric_list_cmp - list_sort comparator that sorts metrics with more events to 985 1095 * the front. tool events are excluded from the count. ··· 1060 1216 { 1061 1217 LIST_HEAD(list); 1062 1218 int ret; 1063 - bool has_match = false; 1219 + struct metricgroup__add_metric_data data = { 1220 + .list = &list, 1221 + .pmu = pmu, 1222 + .metric_name = metric_name, 1223 + .modifier = modifier, 1224 + .metric_no_group = metric_no_group, 1225 + .metric_no_threshold = metric_no_threshold, 1226 + .user_requested_cpu_list = user_requested_cpu_list, 1227 + .system_wide = system_wide, 1228 + .has_match = false, 1229 + }; 1064 1230 1065 - { 1066 - struct metricgroup__add_metric_data data = { 1067 - .list = &list, 1068 - .pmu = pmu, 1069 - .metric_name = metric_name, 1070 - .modifier = modifier, 1071 - .metric_no_group = metric_no_group, 1072 - .metric_no_threshold = metric_no_threshold, 1073 - .user_requested_cpu_list = user_requested_cpu_list, 1074 - .system_wide = system_wide, 1075 - .has_match = false, 1076 - }; 1077 - /* 1078 - * Iterate over all metrics seeing if metric matches either the 1079 - * name or group. When it does add the metric to the list. 1080 - */ 1081 - ret = pmu_metrics_table__for_each_metric(table, metricgroup__add_metric_callback, 1082 - &data); 1083 - if (ret) 1084 - goto out; 1085 - 1086 - has_match = data.has_match; 1087 - } 1088 - { 1089 - struct metricgroup_iter_data data = { 1090 - .fn = metricgroup__add_metric_sys_event_iter, 1091 - .data = (void *) &(struct metricgroup_add_iter_data) { 1092 - .metric_list = &list, 1093 - .pmu = pmu, 1094 - .metric_name = metric_name, 1095 - .modifier = modifier, 1096 - .metric_no_group = metric_no_group, 1097 - .user_requested_cpu_list = user_requested_cpu_list, 1098 - .system_wide = system_wide, 1099 - .has_match = &has_match, 1100 - .ret = &ret, 1101 - .table = table, 1102 - }, 1103 - }; 1104 - 1105 - pmu_for_each_sys_metric(metricgroup__sys_event_iter, &data); 1106 - } 1107 - /* End of pmu events. */ 1108 - if (!has_match) 1231 + /* 1232 + * Iterate over all metrics seeing if metric matches either the 1233 + * name or group. When it does add the metric to the list. 1234 + */ 1235 + ret = metricgroup__for_each_metric(table, metricgroup__add_metric_callback, &data); 1236 + if (!ret && !data.has_match) 1109 1237 ret = -EINVAL; 1110 1238 1111 - out: 1112 1239 /* 1113 1240 * add to metric_list so that they can be released 1114 1241 * even if it's failed
+2 -1
tools/perf/util/metricgroup.h
··· 84 84 const char *str, 85 85 struct rblist *metric_events); 86 86 87 - void metricgroup__print(const struct print_callbacks *print_cb, void *print_state); 87 + int metricgroup__for_each_metric(const struct pmu_metrics_table *table, pmu_metric_iter_fn fn, 88 + void *data); 88 89 bool metricgroup__has_metric_or_groups(const char *pmu, const char *metric_or_groups); 89 90 unsigned int metricgroups__topdown_max_level(void); 90 91 int arch_get_runtimeparam(const struct pmu_metric *pm);
+133
tools/perf/util/print-events.c
··· 381 381 strlist__delete(evt_name_list); 382 382 } 383 383 384 + /** struct mep - RB-tree node for building printing information. */ 385 + struct mep { 386 + /** nd - RB-tree element. */ 387 + struct rb_node nd; 388 + /** @metric_group: Owned metric group name, separated others with ';'. */ 389 + char *metric_group; 390 + const char *metric_name; 391 + const char *metric_desc; 392 + const char *metric_long_desc; 393 + const char *metric_expr; 394 + const char *metric_threshold; 395 + const char *metric_unit; 396 + const char *pmu_name; 397 + }; 398 + 399 + static int mep_cmp(struct rb_node *rb_node, const void *entry) 400 + { 401 + struct mep *a = container_of(rb_node, struct mep, nd); 402 + struct mep *b = (struct mep *)entry; 403 + int ret; 404 + 405 + ret = strcmp(a->metric_group, b->metric_group); 406 + if (ret) 407 + return ret; 408 + 409 + return strcmp(a->metric_name, b->metric_name); 410 + } 411 + 412 + static struct rb_node *mep_new(struct rblist *rl __maybe_unused, const void *entry) 413 + { 414 + struct mep *me = malloc(sizeof(struct mep)); 415 + 416 + if (!me) 417 + return NULL; 418 + 419 + memcpy(me, entry, sizeof(struct mep)); 420 + return &me->nd; 421 + } 422 + 423 + static void mep_delete(struct rblist *rl __maybe_unused, 424 + struct rb_node *nd) 425 + { 426 + struct mep *me = container_of(nd, struct mep, nd); 427 + 428 + zfree(&me->metric_group); 429 + free(me); 430 + } 431 + 432 + static struct mep *mep_lookup(struct rblist *groups, const char *metric_group, 433 + const char *metric_name) 434 + { 435 + struct rb_node *nd; 436 + struct mep me = { 437 + .metric_group = strdup(metric_group), 438 + .metric_name = metric_name, 439 + }; 440 + nd = rblist__find(groups, &me); 441 + if (nd) { 442 + free(me.metric_group); 443 + return container_of(nd, struct mep, nd); 444 + } 445 + rblist__add_node(groups, &me); 446 + nd = rblist__find(groups, &me); 447 + if (nd) 448 + return container_of(nd, struct mep, nd); 449 + return NULL; 450 + } 451 + 452 + static int metricgroup__add_to_mep_groups_callback(const struct pmu_metric *pm, 453 + const struct pmu_metrics_table *table __maybe_unused, 454 + void *vdata) 455 + { 456 + struct rblist *groups = vdata; 457 + const char *g; 458 + char *omg, *mg; 459 + 460 + mg = strdup(pm->metric_group ?: pm->metric_name); 461 + if (!mg) 462 + return -ENOMEM; 463 + omg = mg; 464 + while ((g = strsep(&mg, ";")) != NULL) { 465 + struct mep *me; 466 + 467 + g = skip_spaces(g); 468 + if (strlen(g)) 469 + me = mep_lookup(groups, g, pm->metric_name); 470 + else 471 + me = mep_lookup(groups, pm->metric_name, pm->metric_name); 472 + 473 + if (me) { 474 + me->metric_desc = pm->desc; 475 + me->metric_long_desc = pm->long_desc; 476 + me->metric_expr = pm->metric_expr; 477 + me->metric_threshold = pm->metric_threshold; 478 + me->metric_unit = pm->unit; 479 + me->pmu_name = pm->pmu; 480 + } 481 + } 482 + free(omg); 483 + 484 + return 0; 485 + } 486 + 487 + void metricgroup__print(const struct print_callbacks *print_cb, void *print_state) 488 + { 489 + struct rblist groups; 490 + struct rb_node *node, *next; 491 + const struct pmu_metrics_table *table = pmu_metrics_table__find(); 492 + 493 + rblist__init(&groups); 494 + groups.node_new = mep_new; 495 + groups.node_cmp = mep_cmp; 496 + groups.node_delete = mep_delete; 497 + 498 + metricgroup__for_each_metric(table, metricgroup__add_to_mep_groups_callback, &groups); 499 + 500 + for (node = rb_first_cached(&groups.entries); node; node = next) { 501 + struct mep *me = container_of(node, struct mep, nd); 502 + 503 + print_cb->print_metric(print_state, 504 + me->metric_group, 505 + me->metric_name, 506 + me->metric_desc, 507 + me->metric_long_desc, 508 + me->metric_expr, 509 + me->metric_threshold, 510 + me->metric_unit, 511 + me->pmu_name); 512 + next = rb_next(node); 513 + rblist__remove_node(&groups, node); 514 + } 515 + } 516 + 384 517 /* 385 518 * Print the help text for the event symbols: 386 519 */
+2
tools/perf/util/print-events.h
··· 37 37 void print_symbol_events(const struct print_callbacks *print_cb, void *print_state, 38 38 unsigned int type, const struct event_symbol *syms, 39 39 unsigned int max); 40 + 40 41 void print_tracepoint_events(const struct print_callbacks *print_cb, void *print_state); 42 + void metricgroup__print(const struct print_callbacks *print_cb, void *print_state); 41 43 bool is_event_supported(u8 type, u64 config); 42 44 43 45 #endif /* __PERF_PRINT_EVENTS_H */