~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/builtin-list.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * builtin-list.c
  4  *
  5  * Builtin list command: list all event types
  6  *
  7  * Copyright (C) 2009, Thomas Gleixner <tglx@linutronix.de>
  8  * Copyright (C) 2008-2009, Red Hat Inc, Ingo Molnar <mingo@redhat.com>
  9  * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
 10  */
 11 #include "builtin.h"
 12 
 13 #include "util/print-events.h"
 14 #include "util/pmus.h"
 15 #include "util/pmu.h"
 16 #include "util/debug.h"
 17 #include "util/metricgroup.h"
 18 #include "util/pfm.h"
 19 #include "util/string2.h"
 20 #include "util/strlist.h"
 21 #include "util/strbuf.h"
 22 #include <subcmd/pager.h>
 23 #include <subcmd/parse-options.h>
 24 #include <linux/zalloc.h>
 25 #include <ctype.h>
 26 #include <stdarg.h>
 27 #include <stdio.h>
 28 
 29 /**
 30  * struct print_state - State and configuration passed to the default_print
 31  * functions.
 32  */
 33 struct print_state {
 34         /** @fp: File to write output to. */
 35         FILE *fp;
 36         /**
 37          * @pmu_glob: Optionally restrict PMU and metric matching to PMU or
 38          * debugfs subsystem name.
 39          */
 40         char *pmu_glob;
 41         /** @event_glob: Optional pattern matching glob. */
 42         char *event_glob;
 43         /** @name_only: Print event or metric names only. */
 44         bool name_only;
 45         /** @desc: Print the event or metric description. */
 46         bool desc;
 47         /** @long_desc: Print longer event or metric description. */
 48         bool long_desc;
 49         /** @deprecated: Print deprecated events or metrics. */
 50         bool deprecated;
 51         /**
 52          * @detailed: Print extra information on the perf event such as names
 53          * and expressions used internally by events.
 54          */
 55         bool detailed;
 56         /** @metrics: Controls printing of metric and metric groups. */
 57         bool metrics;
 58         /** @metricgroups: Controls printing of metric and metric groups. */
 59         bool metricgroups;
 60         /** @last_topic: The last printed event topic. */
 61         char *last_topic;
 62         /** @last_metricgroups: The last printed metric group. */
 63         char *last_metricgroups;
 64         /** @visited_metrics: Metrics that are printed to avoid duplicates. */
 65         struct strlist *visited_metrics;
 66 };
 67 
 68 static void default_print_start(void *ps)
 69 {
 70         struct print_state *print_state = ps;
 71 
 72         if (!print_state->name_only && pager_in_use()) {
 73                 fprintf(print_state->fp,
 74                         "\nList of pre-defined events (to be used in -e or -M):\n\n");
 75         }
 76 }
 77 
 78 static void default_print_end(void *print_state __maybe_unused) {}
 79 
 80 static const char *skip_spaces_or_commas(const char *str)
 81 {
 82         while (isspace(*str) || *str == ',')
 83                 ++str;
 84         return str;
 85 }
 86 
 87 static void wordwrap(FILE *fp, const char *s, int start, int max, int corr)
 88 {
 89         int column = start;
 90         int n;
 91         bool saw_newline = false;
 92         bool comma = false;
 93 
 94         while (*s) {
 95                 int wlen = strcspn(s, " ,\t\n");
 96                 const char *sep = comma ? "," : " ";
 97 
 98                 if ((column + wlen >= max && column > start) || saw_newline) {
 99                         fprintf(fp, comma ? ",\n%*s" : "\n%*s", start, "");
100                         column = start + corr;
101                 }
102                 if (column <= start)
103                         sep = "";
104                 n = fprintf(fp, "%s%.*s", sep, wlen, s);
105                 if (n <= 0)
106                         break;
107                 saw_newline = s[wlen] == '\n';
108                 s += wlen;
109                 comma = s[0] == ',';
110                 column += n;
111                 s = skip_spaces_or_commas(s);
112         }
113 }
114 
115 static void default_print_event(void *ps, const char *pmu_name, const char *topic,
116                                 const char *event_name, const char *event_alias,
117                                 const char *scale_unit __maybe_unused,
118                                 bool deprecated, const char *event_type_desc,
119                                 const char *desc, const char *long_desc,
120                                 const char *encoding_desc)
121 {
122         struct print_state *print_state = ps;
123         int pos;
124         FILE *fp = print_state->fp;
125 
126         if (deprecated && !print_state->deprecated)
127                 return;
128 
129         if (print_state->pmu_glob && pmu_name && !strglobmatch(pmu_name, print_state->pmu_glob))
130                 return;
131 
132         if (print_state->event_glob &&
133             (!event_name || !strglobmatch(event_name, print_state->event_glob)) &&
134             (!event_alias || !strglobmatch(event_alias, print_state->event_glob)) &&
135             (!topic || !strglobmatch_nocase(topic, print_state->event_glob)))
136                 return;
137 
138         if (print_state->name_only) {
139                 if (event_alias && strlen(event_alias))
140                         fprintf(fp, "%s ", event_alias);
141                 else
142                         fprintf(fp, "%s ", event_name);
143                 return;
144         }
145 
146         if (strcmp(print_state->last_topic, topic ?: "")) {
147                 if (topic)
148                         fprintf(fp, "\n%s:\n", topic);
149                 zfree(&print_state->last_topic);
150                 print_state->last_topic = strdup(topic ?: "");
151         }
152 
153         if (event_alias && strlen(event_alias))
154                 pos = fprintf(fp, "  %s OR %s", event_name, event_alias);
155         else
156                 pos = fprintf(fp, "  %s", event_name);
157 
158         if (!topic && event_type_desc) {
159                 for (; pos < 53; pos++)
160                         fputc(' ', fp);
161                 fprintf(fp, "[%s]\n", event_type_desc);
162         } else
163                 fputc('\n', fp);
164 
165         if (long_desc && print_state->long_desc) {
166                 fprintf(fp, "%*s", 8, "[");
167                 wordwrap(fp, long_desc, 8, pager_get_columns(), 0);
168                 fprintf(fp, "]\n");
169         } else if (desc && print_state->desc) {
170                 char *desc_with_unit = NULL;
171                 int desc_len = -1;
172 
173                 if (pmu_name && strcmp(pmu_name, "default_core")) {
174                         desc_len = strlen(desc);
175                         desc_len = asprintf(&desc_with_unit,
176                                             desc[desc_len - 1] != '.'
177                                               ? "%s. Unit: %s" : "%s Unit: %s",
178                                             desc, pmu_name);
179                 }
180                 fprintf(fp, "%*s", 8, "[");
181                 wordwrap(fp, desc_len > 0 ? desc_with_unit : desc, 8, pager_get_columns(), 0);
182                 fprintf(fp, "]\n");
183                 free(desc_with_unit);
184         }
185 
186         if (print_state->detailed && encoding_desc) {
187                 fprintf(fp, "%*s", 8, "");
188                 wordwrap(fp, encoding_desc, 8, pager_get_columns(), 0);
189                 fputc('\n', fp);
190         }
191 }
192 
193 static void default_print_metric(void *ps,
194                                 const char *group,
195                                 const char *name,
196                                 const char *desc,
197                                 const char *long_desc,
198                                 const char *expr,
199                                 const char *threshold,
200                                 const char *unit __maybe_unused)
201 {
202         struct print_state *print_state = ps;
203         FILE *fp = print_state->fp;
204 
205         if (print_state->event_glob &&
206             (!print_state->metrics || !name || !strglobmatch(name, print_state->event_glob)) &&
207             (!print_state->metricgroups || !group || !strglobmatch(group, print_state->event_glob)))
208                 return;
209 
210         if (!print_state->name_only && !print_state->last_metricgroups) {
211                 if (print_state->metricgroups) {
212                         fprintf(fp, "\nMetric Groups:\n");
213                         if (!print_state->metrics)
214                                 fputc('\n', fp);
215                 } else {
216                         fprintf(fp, "\nMetrics:\n\n");
217                 }
218         }
219         if (!print_state->last_metricgroups ||
220             strcmp(print_state->last_metricgroups, group ?: "")) {
221                 if (group && print_state->metricgroups) {
222                         if (print_state->name_only) {
223                                 fprintf(fp, "%s ", group);
224                         } else {
225                                 const char *gdesc = print_state->desc
226                                         ? describe_metricgroup(group)
227                                         : NULL;
228                                 const char *print_colon = "";
229 
230                                 if (print_state->metrics) {
231                                         print_colon = ":";
232                                         fputc('\n', fp);
233                                 }
234 
235                                 if (gdesc)
236                                         fprintf(fp, "%s%s [%s]\n", group, print_colon, gdesc);
237                                 else
238                                         fprintf(fp, "%s%s\n", group, print_colon);
239                         }
240                 }
241                 zfree(&print_state->last_metricgroups);
242                 print_state->last_metricgroups = strdup(group ?: "");
243         }
244         if (!print_state->metrics)
245                 return;
246 
247         if (print_state->name_only) {
248                 if (print_state->metrics &&
249                     !strlist__has_entry(print_state->visited_metrics, name)) {
250                         fprintf(fp, "%s ", name);
251                         strlist__add(print_state->visited_metrics, name);
252                 }
253                 return;
254         }
255         fprintf(fp, "  %s\n", name);
256 
257         if (long_desc && print_state->long_desc) {
258                 fprintf(fp, "%*s", 8, "[");
259                 wordwrap(fp, long_desc, 8, pager_get_columns(), 0);
260                 fprintf(fp, "]\n");
261         } else if (desc && print_state->desc) {
262                 fprintf(fp, "%*s", 8, "[");
263                 wordwrap(fp, desc, 8, pager_get_columns(), 0);
264                 fprintf(fp, "]\n");
265         }
266         if (expr && print_state->detailed) {
267                 fprintf(fp, "%*s", 8, "[");
268                 wordwrap(fp, expr, 8, pager_get_columns(), 0);
269                 fprintf(fp, "]\n");
270         }
271         if (threshold && print_state->detailed) {
272                 fprintf(fp, "%*s", 8, "[");
273                 wordwrap(fp, threshold, 8, pager_get_columns(), 0);
274                 fprintf(fp, "]\n");
275         }
276 }
277 
278 struct json_print_state {
279         /** @fp: File to write output to. */
280         FILE *fp;
281         /** Should a separator be printed prior to the next item? */
282         bool need_sep;
283 };
284 
285 static void json_print_start(void *ps)
286 {
287         struct json_print_state *print_state = ps;
288         FILE *fp = print_state->fp;
289 
290         fprintf(fp, "[\n");
291 }
292 
293 static void json_print_end(void *ps)
294 {
295         struct json_print_state *print_state = ps;
296         FILE *fp = print_state->fp;
297 
298         fprintf(fp, "%s]\n", print_state->need_sep ? "\n" : "");
299 }
300 
301 static void fix_escape_fprintf(FILE *fp, struct strbuf *buf, const char *fmt, ...)
302 {
303         va_list args;
304 
305         va_start(args, fmt);
306         strbuf_setlen(buf, 0);
307         for (size_t fmt_pos = 0; fmt_pos < strlen(fmt); fmt_pos++) {
308                 switch (fmt[fmt_pos]) {
309                 case '%':
310                         fmt_pos++;
311                         switch (fmt[fmt_pos]) {
312                         case 's': {
313                                 const char *s = va_arg(args, const char*);
314 
315                                 strbuf_addstr(buf, s);
316                                 break;
317                         }
318                         case 'S': {
319                                 const char *s = va_arg(args, const char*);
320 
321                                 for (size_t s_pos = 0; s_pos < strlen(s); s_pos++) {
322                                         switch (s[s_pos]) {
323                                         case '\n':
324                                                 strbuf_addstr(buf, "\\n");
325                                                 break;
326                                         case '\r':
327                                                 strbuf_addstr(buf, "\\r");
328                                                 break;
329                                         case '\\':
330                                                 fallthrough;
331                                         case '\"':
332                                                 strbuf_addch(buf, '\\');
333                                                 fallthrough;
334                                         default:
335                                                 strbuf_addch(buf, s[s_pos]);
336                                                 break;
337                                         }
338                                 }
339                                 break;
340                         }
341                         default:
342                                 pr_err("Unexpected format character '%c'\n", fmt[fmt_pos]);
343                                 strbuf_addch(buf, '%');
344                                 strbuf_addch(buf, fmt[fmt_pos]);
345                         }
346                         break;
347                 default:
348                         strbuf_addch(buf, fmt[fmt_pos]);
349                         break;
350                 }
351         }
352         va_end(args);
353         fputs(buf->buf, fp);
354 }
355 
356 static void json_print_event(void *ps, const char *pmu_name, const char *topic,
357                              const char *event_name, const char *event_alias,
358                              const char *scale_unit,
359                              bool deprecated, const char *event_type_desc,
360                              const char *desc, const char *long_desc,
361                              const char *encoding_desc)
362 {
363         struct json_print_state *print_state = ps;
364         bool need_sep = false;
365         FILE *fp = print_state->fp;
366         struct strbuf buf;
367 
368         strbuf_init(&buf, 0);
369         fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : "");
370         print_state->need_sep = true;
371         if (pmu_name) {
372                 fix_escape_fprintf(fp, &buf, "\t\"Unit\": \"%S\"", pmu_name);
373                 need_sep = true;
374         }
375         if (topic) {
376                 fix_escape_fprintf(fp, &buf, "%s\t\"Topic\": \"%S\"",
377                                    need_sep ? ",\n" : "",
378                                    topic);
379                 need_sep = true;
380         }
381         if (event_name) {
382                 fix_escape_fprintf(fp, &buf, "%s\t\"EventName\": \"%S\"",
383                                    need_sep ? ",\n" : "",
384                                    event_name);
385                 need_sep = true;
386         }
387         if (event_alias && strlen(event_alias)) {
388                 fix_escape_fprintf(fp, &buf, "%s\t\"EventAlias\": \"%S\"",
389                                    need_sep ? ",\n" : "",
390                                    event_alias);
391                 need_sep = true;
392         }
393         if (scale_unit && strlen(scale_unit)) {
394                 fix_escape_fprintf(fp, &buf, "%s\t\"ScaleUnit\": \"%S\"",
395                                    need_sep ? ",\n" : "",
396                                    scale_unit);
397                 need_sep = true;
398         }
399         if (event_type_desc) {
400                 fix_escape_fprintf(fp, &buf, "%s\t\"EventType\": \"%S\"",
401                                    need_sep ? ",\n" : "",
402                                    event_type_desc);
403                 need_sep = true;
404         }
405         if (deprecated) {
406                 fix_escape_fprintf(fp, &buf, "%s\t\"Deprecated\": \"%S\"",
407                                    need_sep ? ",\n" : "",
408                                    deprecated ? "1" : "");
409                 need_sep = true;
410         }
411         if (desc) {
412                 fix_escape_fprintf(fp, &buf, "%s\t\"BriefDescription\": \"%S\"",
413                                    need_sep ? ",\n" : "",
414                                    desc);
415                 need_sep = true;
416         }
417         if (long_desc) {
418                 fix_escape_fprintf(fp, &buf, "%s\t\"PublicDescription\": \"%S\"",
419                                    need_sep ? ",\n" : "",
420                                    long_desc);
421                 need_sep = true;
422         }
423         if (encoding_desc) {
424                 fix_escape_fprintf(fp, &buf, "%s\t\"Encoding\": \"%S\"",
425                                    need_sep ? ",\n" : "",
426                                    encoding_desc);
427                 need_sep = true;
428         }
429         fprintf(fp, "%s}", need_sep ? "\n" : "");
430         strbuf_release(&buf);
431 }
432 
433 static void json_print_metric(void *ps __maybe_unused, const char *group,
434                               const char *name, const char *desc,
435                               const char *long_desc, const char *expr,
436                               const char *threshold, const char *unit)
437 {
438         struct json_print_state *print_state = ps;
439         bool need_sep = false;
440         FILE *fp = print_state->fp;
441         struct strbuf buf;
442 
443         strbuf_init(&buf, 0);
444         fprintf(fp, "%s{\n", print_state->need_sep ? ",\n" : "");
445         print_state->need_sep = true;
446         if (group) {
447                 fix_escape_fprintf(fp, &buf, "\t\"MetricGroup\": \"%S\"", group);
448                 need_sep = true;
449         }
450         if (name) {
451                 fix_escape_fprintf(fp, &buf, "%s\t\"MetricName\": \"%S\"",
452                                    need_sep ? ",\n" : "",
453                                    name);
454                 need_sep = true;
455         }
456         if (expr) {
457                 fix_escape_fprintf(fp, &buf, "%s\t\"MetricExpr\": \"%S\"",
458                                    need_sep ? ",\n" : "",
459                                    expr);
460                 need_sep = true;
461         }
462         if (threshold) {
463                 fix_escape_fprintf(fp, &buf, "%s\t\"MetricThreshold\": \"%S\"",
464                                    need_sep ? ",\n" : "",
465                                    threshold);
466                 need_sep = true;
467         }
468         if (unit) {
469                 fix_escape_fprintf(fp, &buf, "%s\t\"ScaleUnit\": \"%S\"",
470                                    need_sep ? ",\n" : "",
471                                    unit);
472                 need_sep = true;
473         }
474         if (desc) {
475                 fix_escape_fprintf(fp, &buf, "%s\t\"BriefDescription\": \"%S\"",
476                                    need_sep ? ",\n" : "",
477                                    desc);
478                 need_sep = true;
479         }
480         if (long_desc) {
481                 fix_escape_fprintf(fp, &buf, "%s\t\"PublicDescription\": \"%S\"",
482                                    need_sep ? ",\n" : "",
483                                    long_desc);
484                 need_sep = true;
485         }
486         fprintf(fp, "%s}", need_sep ? "\n" : "");
487         strbuf_release(&buf);
488 }
489 
490 static bool json_skip_duplicate_pmus(void *ps __maybe_unused)
491 {
492         return false;
493 }
494 
495 static bool default_skip_duplicate_pmus(void *ps)
496 {
497         struct print_state *print_state = ps;
498 
499         return !print_state->long_desc;
500 }
501 
502 int cmd_list(int argc, const char **argv)
503 {
504         int i, ret = 0;
505         struct print_state default_ps = {
506                 .fp = stdout,
507                 .desc = true,
508         };
509         struct print_state json_ps = {
510                 .fp = stdout,
511         };
512         void *ps = &default_ps;
513         struct print_callbacks print_cb = {
514                 .print_start = default_print_start,
515                 .print_end = default_print_end,
516                 .print_event = default_print_event,
517                 .print_metric = default_print_metric,
518                 .skip_duplicate_pmus = default_skip_duplicate_pmus,
519         };
520         const char *cputype = NULL;
521         const char *unit_name = NULL;
522         const char *output_path = NULL;
523         bool json = false;
524         struct option list_options[] = {
525                 OPT_BOOLEAN(0, "raw-dump", &default_ps.name_only, "Dump raw events"),
526                 OPT_BOOLEAN('j', "json", &json, "JSON encode events and metrics"),
527                 OPT_BOOLEAN('d', "desc", &default_ps.desc,
528                             "Print extra event descriptions. --no-desc to not print."),
529                 OPT_BOOLEAN('v', "long-desc", &default_ps.long_desc,
530                             "Print longer event descriptions."),
531                 OPT_BOOLEAN(0, "details", &default_ps.detailed,
532                             "Print information on the perf event names and expressions used internally by events."),
533                 OPT_STRING('o', "output", &output_path, "file", "output file name"),
534                 OPT_BOOLEAN(0, "deprecated", &default_ps.deprecated,
535                             "Print deprecated events."),
536                 OPT_STRING(0, "cputype", &cputype, "cpu type",
537                            "Limit PMU or metric printing to the given PMU (e.g. cpu, core or atom)."),
538                 OPT_STRING(0, "unit", &unit_name, "PMU name",
539                            "Limit PMU or metric printing to the specified PMU."),
540                 OPT_INCR(0, "debug", &verbose,
541                              "Enable debugging output"),
542                 OPT_END()
543         };
544         const char * const list_usage[] = {
545 #ifdef HAVE_LIBPFM
546                 "perf list [<options>] [hw|sw|cache|tracepoint|pmu|sdt|metric|metricgroup|event_glob|pfm]",
547 #else
548                 "perf list [<options>] [hw|sw|cache|tracepoint|pmu|sdt|metric|metricgroup|event_glob]",
549 #endif
550                 NULL
551         };
552 
553         set_option_flag(list_options, 0, "raw-dump", PARSE_OPT_HIDDEN);
554         /* Hide hybrid flag for the more generic 'unit' flag. */
555         set_option_flag(list_options, 0, "cputype", PARSE_OPT_HIDDEN);
556 
557         argc = parse_options(argc, argv, list_options, list_usage,
558                              PARSE_OPT_STOP_AT_NON_OPTION);
559 
560         if (output_path) {
561                 default_ps.fp = fopen(output_path, "w");
562                 json_ps.fp = default_ps.fp;
563         }
564 
565         setup_pager();
566 
567         if (!default_ps.name_only)
568                 setup_pager();
569 
570         if (json) {
571                 print_cb = (struct print_callbacks){
572                         .print_start = json_print_start,
573                         .print_end = json_print_end,
574                         .print_event = json_print_event,
575                         .print_metric = json_print_metric,
576                         .skip_duplicate_pmus = json_skip_duplicate_pmus,
577                 };
578                 ps = &json_ps;
579         } else {
580                 default_ps.last_topic = strdup("");
581                 assert(default_ps.last_topic);
582                 default_ps.visited_metrics = strlist__new(NULL, NULL);
583                 assert(default_ps.visited_metrics);
584                 if (unit_name)
585                         default_ps.pmu_glob = strdup(unit_name);
586                 else if (cputype) {
587                         const struct perf_pmu *pmu = perf_pmus__pmu_for_pmu_filter(cputype);
588 
589                         if (!pmu) {
590                                 pr_err("ERROR: cputype is not supported!\n");
591                                 ret = -1;
592                                 goto out;
593                         }
594                         default_ps.pmu_glob = strdup(pmu->name);
595                 }
596         }
597         print_cb.print_start(ps);
598 
599         if (argc == 0) {
600                 default_ps.metrics = true;
601                 default_ps.metricgroups = true;
602                 print_events(&print_cb, ps);
603                 goto out;
604         }
605 
606         for (i = 0; i < argc; ++i) {
607                 char *sep, *s;
608 
609                 if (strcmp(argv[i], "tracepoint") == 0)
610                         print_tracepoint_events(&print_cb, ps);
611                 else if (strcmp(argv[i], "hw") == 0 ||
612                          strcmp(argv[i], "hardware") == 0)
613                         print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE,
614                                         event_symbols_hw, PERF_COUNT_HW_MAX);
615                 else if (strcmp(argv[i], "sw") == 0 ||
616                          strcmp(argv[i], "software") == 0) {
617                         print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE,
618                                         event_symbols_sw, PERF_COUNT_SW_MAX);
619                         print_tool_events(&print_cb, ps);
620                 } else if (strcmp(argv[i], "cache") == 0 ||
621                          strcmp(argv[i], "hwcache") == 0)
622                         print_hwcache_events(&print_cb, ps);
623                 else if (strcmp(argv[i], "pmu") == 0)
624                         perf_pmus__print_pmu_events(&print_cb, ps);
625                 else if (strcmp(argv[i], "sdt") == 0)
626                         print_sdt_events(&print_cb, ps);
627                 else if (strcmp(argv[i], "metric") == 0 || strcmp(argv[i], "metrics") == 0) {
628                         default_ps.metricgroups = false;
629                         default_ps.metrics = true;
630                         metricgroup__print(&print_cb, ps);
631                 } else if (strcmp(argv[i], "metricgroup") == 0 ||
632                            strcmp(argv[i], "metricgroups") == 0) {
633                         default_ps.metricgroups = true;
634                         default_ps.metrics = false;
635                         metricgroup__print(&print_cb, ps);
636                 }
637 #ifdef HAVE_LIBPFM
638                 else if (strcmp(argv[i], "pfm") == 0)
639                         print_libpfm_events(&print_cb, ps);
640 #endif
641                 else if ((sep = strchr(argv[i], ':')) != NULL) {
642                         char *old_pmu_glob = default_ps.pmu_glob;
643 
644                         default_ps.event_glob = strdup(argv[i]);
645                         if (!default_ps.event_glob) {
646                                 ret = -1;
647                                 goto out;
648                         }
649 
650                         print_tracepoint_events(&print_cb, ps);
651                         print_sdt_events(&print_cb, ps);
652                         default_ps.metrics = true;
653                         default_ps.metricgroups = true;
654                         metricgroup__print(&print_cb, ps);
655                         zfree(&default_ps.event_glob);
656                         default_ps.pmu_glob = old_pmu_glob;
657                 } else {
658                         if (asprintf(&s, "*%s*", argv[i]) < 0) {
659                                 printf("Critical: Not enough memory! Trying to continue...\n");
660                                 continue;
661                         }
662                         default_ps.event_glob = s;
663                         print_symbol_events(&print_cb, ps, PERF_TYPE_HARDWARE,
664                                         event_symbols_hw, PERF_COUNT_HW_MAX);
665                         print_symbol_events(&print_cb, ps, PERF_TYPE_SOFTWARE,
666                                         event_symbols_sw, PERF_COUNT_SW_MAX);
667                         print_tool_events(&print_cb, ps);
668                         print_hwcache_events(&print_cb, ps);
669                         perf_pmus__print_pmu_events(&print_cb, ps);
670                         print_tracepoint_events(&print_cb, ps);
671                         print_sdt_events(&print_cb, ps);
672                         default_ps.metrics = true;
673                         default_ps.metricgroups = true;
674                         metricgroup__print(&print_cb, ps);
675                         free(s);
676                 }
677         }
678 
679 out:
680         print_cb.print_end(ps);
681         free(default_ps.pmu_glob);
682         free(default_ps.last_topic);
683         free(default_ps.last_metricgroups);
684         strlist__delete(default_ps.visited_metrics);
685         if (output_path)
686                 fclose(default_ps.fp);
687 
688         return ret;
689 }
690 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php