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

perf stat: Pass through 'struct outstate'

Now most of the print functions take a pointer to the struct outstate.
We have one in the evlist__print_counters() and pass it through the
child functions.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Ian Rogers <irogers@google.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Athira Jajeev <atrajeev@linux.vnet.ibm.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: James Clark <james.clark@arm.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Xing Zhengjun <zhengjun.xing@linux.intel.com>
Link: https://lore.kernel.org/r/20221123180208.2068936-13-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
5f334d88 01577597

+50 -63
+2 -2
tools/perf/arch/x86/util/iostat.c
··· 449 449 450 450 void iostat_print_counters(struct evlist *evlist, 451 451 struct perf_stat_config *config, struct timespec *ts, 452 - char *prefix, iostat_print_counter_t print_cnt_cb) 452 + char *prefix, iostat_print_counter_t print_cnt_cb, void *arg) 453 453 { 454 454 void *perf_device = NULL; 455 455 struct evsel *counter = evlist__first(evlist); ··· 464 464 iostat_prefix(evlist, config, prefix, ts); 465 465 fprintf(config->output, "\n%s", prefix); 466 466 } 467 - print_cnt_cb(config, counter, prefix); 467 + print_cnt_cb(config, counter, arg); 468 468 } 469 469 fputc('\n', config->output); 470 470 }
+2 -1
tools/perf/util/iostat.c
··· 48 48 struct perf_stat_config *config __maybe_unused, 49 49 struct timespec *ts __maybe_unused, 50 50 char *prefix __maybe_unused, 51 - iostat_print_counter_t print_cnt_cb __maybe_unused) 51 + iostat_print_counter_t print_cnt_cb __maybe_unused, 52 + void *arg __maybe_unused) 52 53 { 53 54 }
+2 -2
tools/perf/util/iostat.h
··· 28 28 29 29 extern enum iostat_mode_t iostat_mode; 30 30 31 - typedef void (*iostat_print_counter_t)(struct perf_stat_config *, struct evsel *, const char *); 31 + typedef void (*iostat_print_counter_t)(struct perf_stat_config *, struct evsel *, void *); 32 32 33 33 int iostat_prepare(struct evlist *evlist, struct perf_stat_config *config); 34 34 int iostat_parse(const struct option *opt, const char *str, ··· 42 42 struct perf_stat_output_ctx *out); 43 43 void iostat_print_counters(struct evlist *evlist, 44 44 struct perf_stat_config *config, struct timespec *ts, 45 - char *prefix, iostat_print_counter_t print_cnt_cb); 45 + char *prefix, iostat_print_counter_t print_cnt_cb, void *arg); 46 46 47 47 #endif /* _IOSTAT_H */
+44 -58
tools/perf/util/stat-display.c
··· 796 796 797 797 static void print_counter_aggrdata(struct perf_stat_config *config, 798 798 struct evsel *counter, int s, 799 - const char *prefix) 799 + struct outstate *os) 800 800 { 801 801 FILE *output = config->output; 802 802 u64 ena, run, val; ··· 806 806 struct aggr_cpu_id id = config->aggr_map->map[s]; 807 807 double avg = aggr->counts.val; 808 808 bool metric_only = config->metric_only; 809 - struct outstate os = { 810 - .fh = config->output, 811 - .prefix = prefix ? prefix : "", 812 - .id = id, 813 - .nr = aggr->nr, 814 - .evsel = counter, 815 - }; 809 + 810 + os->id = id; 811 + os->nr = aggr->nr; 812 + os->evsel = counter; 816 813 817 814 if (counter->supported && aggr->nr == 0) 818 815 return; ··· 821 824 run = aggr->counts.run; 822 825 823 826 if (!metric_only) { 824 - if (prefix) 825 - fprintf(output, "%s", prefix); 827 + if (os->prefix) 828 + fprintf(output, "%s", os->prefix); 826 829 else if (config->summary && config->csv_output && 827 830 !config->no_csv_summary && !config->interval) 828 831 fprintf(output, "%s%s", "summary", config->csv_sep); ··· 830 833 831 834 uval = val * counter->scale; 832 835 833 - printout(config, &os, uval, run, ena, avg, s); 836 + printout(config, os, uval, run, ena, avg, s); 834 837 835 838 if (!metric_only) 836 839 fputc('\n', output); ··· 868 871 869 872 static void print_aggr(struct perf_stat_config *config, 870 873 struct evlist *evlist, 871 - const char *prefix) 874 + struct outstate *os) 872 875 { 873 876 struct evsel *counter; 874 - struct outstate os = { 875 - .prefix = prefix, 876 - }; 877 877 int s; 878 878 879 879 if (!config->aggr_map || !config->aggr_get_id) ··· 881 887 * Without each counter has its own line. 882 888 */ 883 889 for (s = 0; s < config->aggr_map->nr; s++) { 884 - print_metric_begin(config, evlist, &os, s); 890 + print_metric_begin(config, evlist, os, s); 885 891 886 892 evlist__for_each_entry(evlist, counter) { 887 893 if (counter->merged_stat) 888 894 continue; 889 895 890 - print_counter_aggrdata(config, counter, s, prefix); 896 + print_counter_aggrdata(config, counter, s, os); 891 897 } 892 898 print_metric_end(config); 893 899 } ··· 895 901 896 902 static void print_aggr_cgroup(struct perf_stat_config *config, 897 903 struct evlist *evlist, 898 - const char *prefix) 904 + struct outstate *os) 899 905 { 900 906 struct evsel *counter, *evsel; 901 - struct outstate os = { 902 - .prefix = prefix, 903 - }; 904 907 int s; 905 908 906 909 if (!config->aggr_map || !config->aggr_get_id) 907 910 return; 908 911 909 912 evlist__for_each_entry(evlist, evsel) { 910 - if (os.cgrp == evsel->cgrp) 913 + if (os->cgrp == evsel->cgrp) 911 914 continue; 912 915 913 - os.cgrp = evsel->cgrp; 916 + os->cgrp = evsel->cgrp; 914 917 915 918 for (s = 0; s < config->aggr_map->nr; s++) { 916 - print_metric_begin(config, evlist, &os, s); 919 + print_metric_begin(config, evlist, os, s); 917 920 918 921 evlist__for_each_entry(evlist, counter) { 919 922 if (counter->merged_stat) 920 923 continue; 921 924 922 - if (counter->cgrp != os.cgrp) 925 + if (counter->cgrp != os->cgrp) 923 926 continue; 924 927 925 - print_counter_aggrdata(config, counter, s, prefix); 928 + print_counter_aggrdata(config, counter, s, os); 926 929 } 927 930 print_metric_end(config); 928 931 } ··· 927 936 } 928 937 929 938 static void print_counter(struct perf_stat_config *config, 930 - struct evsel *counter, const char *prefix) 939 + struct evsel *counter, struct outstate *os) 931 940 { 932 941 int s; 933 942 ··· 939 948 return; 940 949 941 950 for (s = 0; s < config->aggr_map->nr; s++) { 942 - print_counter_aggrdata(config, counter, s, prefix); 951 + print_counter_aggrdata(config, counter, s, os); 943 952 } 944 953 } 945 954 946 955 static void print_no_aggr_metric(struct perf_stat_config *config, 947 956 struct evlist *evlist, 948 - const char *prefix) 957 + struct outstate *os) 949 958 { 950 959 int all_idx; 951 960 struct perf_cpu cpu; 952 - struct outstate os = { 953 - .prefix = prefix, 954 - }; 955 961 956 962 perf_cpu_map__for_each_cpu(cpu, all_idx, evlist->core.user_requested_cpus) { 957 963 struct evsel *counter; ··· 963 975 if (counter_idx < 0) 964 976 continue; 965 977 966 - os.evsel = counter; 967 - os.id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); 978 + os->evsel = counter; 979 + os->id = aggr_cpu_id__cpu(cpu, /*data=*/NULL); 968 980 if (first) { 969 - print_metric_begin(config, evlist, &os, counter_idx); 981 + print_metric_begin(config, evlist, os, counter_idx); 970 982 first = false; 971 983 } 972 984 val = ps->aggr[counter_idx].counts.val; ··· 974 986 run = ps->aggr[counter_idx].counts.run; 975 987 976 988 uval = val * counter->scale; 977 - printout(config, &os, uval, run, ena, 1.0, counter_idx); 989 + printout(config, os, uval, run, ena, 1.0, counter_idx); 978 990 } 979 991 if (!first) 980 992 print_metric_end(config); ··· 1292 1304 } 1293 1305 1294 1306 static void print_percore(struct perf_stat_config *config, 1295 - struct evsel *counter, const char *prefix) 1307 + struct evsel *counter, struct outstate *os) 1296 1308 { 1297 1309 bool metric_only = config->metric_only; 1298 1310 FILE *output = config->output; ··· 1303 1315 return; 1304 1316 1305 1317 if (config->percore_show_thread) 1306 - return print_counter(config, counter, prefix); 1318 + return print_counter(config, counter, os); 1307 1319 1308 1320 core_map = cpu_aggr_map__empty_new(config->aggr_map->nr); 1309 1321 if (core_map == NULL) { ··· 1325 1337 if (found) 1326 1338 continue; 1327 1339 1328 - print_counter_aggrdata(config, counter, s, prefix); 1340 + print_counter_aggrdata(config, counter, s, os); 1329 1341 1330 1342 core_map->map[c++] = core_id; 1331 1343 } ··· 1336 1348 } 1337 1349 1338 1350 static void print_cgroup_counter(struct perf_stat_config *config, struct evlist *evlist, 1339 - const char *prefix) 1351 + struct outstate *os) 1340 1352 { 1341 1353 struct evsel *counter; 1342 - struct outstate os = { 1343 - .prefix = prefix, 1344 - }; 1345 1354 1346 1355 evlist__for_each_entry(evlist, counter) { 1347 - if (os.cgrp != counter->cgrp) { 1348 - if (os.cgrp != NULL) 1356 + if (os->cgrp != counter->cgrp) { 1357 + if (os->cgrp != NULL) 1349 1358 print_metric_end(config); 1350 1359 1351 - os.cgrp = counter->cgrp; 1352 - print_metric_begin(config, evlist, &os, /*aggr_idx=*/0); 1360 + os->cgrp = counter->cgrp; 1361 + print_metric_begin(config, evlist, os, /*aggr_idx=*/0); 1353 1362 } 1354 1363 1355 - print_counter(config, counter, prefix); 1364 + print_counter(config, counter, os); 1356 1365 } 1357 - if (os.cgrp) 1366 + if (os->cgrp) 1358 1367 print_metric_end(config); 1359 1368 } 1360 1369 1361 1370 void evlist__print_counters(struct evlist *evlist, struct perf_stat_config *config, 1362 - struct target *_target, struct timespec *ts, int argc, const char **argv) 1371 + struct target *_target, struct timespec *ts, 1372 + int argc, const char **argv) 1363 1373 { 1364 1374 bool metric_only = config->metric_only; 1365 1375 int interval = config->interval; ··· 1383 1397 case AGGR_SOCKET: 1384 1398 case AGGR_NODE: 1385 1399 if (config->cgroup_list) 1386 - print_aggr_cgroup(config, evlist, os.prefix); 1400 + print_aggr_cgroup(config, evlist, &os); 1387 1401 else 1388 - print_aggr(config, evlist, os.prefix); 1402 + print_aggr(config, evlist, &os); 1389 1403 break; 1390 1404 case AGGR_THREAD: 1391 1405 case AGGR_GLOBAL: 1392 1406 if (config->iostat_run) { 1393 1407 iostat_print_counters(evlist, config, ts, buf, 1394 - print_counter); 1408 + (iostat_print_counter_t)print_counter, &os); 1395 1409 } else if (config->cgroup_list) { 1396 - print_cgroup_counter(config, evlist, os.prefix); 1410 + print_cgroup_counter(config, evlist, &os); 1397 1411 } else { 1398 1412 print_metric_begin(config, evlist, &os, /*aggr_idx=*/0); 1399 1413 evlist__for_each_entry(evlist, counter) { 1400 - print_counter(config, counter, os.prefix); 1414 + print_counter(config, counter, &os); 1401 1415 } 1402 1416 print_metric_end(config); 1403 1417 } 1404 1418 break; 1405 1419 case AGGR_NONE: 1406 1420 if (metric_only) 1407 - print_no_aggr_metric(config, evlist, os.prefix); 1421 + print_no_aggr_metric(config, evlist, &os); 1408 1422 else { 1409 1423 evlist__for_each_entry(evlist, counter) { 1410 1424 if (counter->percore) 1411 - print_percore(config, counter, os.prefix); 1425 + print_percore(config, counter, &os); 1412 1426 else 1413 - print_counter(config, counter, os.prefix); 1427 + print_counter(config, counter, &os); 1414 1428 } 1415 1429 } 1416 1430 break;