aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-script.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r--tools/perf/builtin-script.c171
1 files changed, 122 insertions, 49 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index ac574ea23917..6cf811acc41b 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -49,23 +49,52 @@ struct output_option {
49}; 49};
50 50
51/* default set to maintain compatibility with current format */ 51/* default set to maintain compatibility with current format */
52static u64 output_fields[PERF_TYPE_MAX] = { 52static struct {
53 [PERF_TYPE_HARDWARE] = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | \ 53 bool user_set;
54 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | \ 54 u64 fields;
55 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM, 55 u64 invalid_fields;
56 56} output[PERF_TYPE_MAX] = {
57 [PERF_TYPE_SOFTWARE] = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | \ 57
58 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | \ 58 [PERF_TYPE_HARDWARE] = {
59 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM, 59 .user_set = false,
60 60
61 [PERF_TYPE_TRACEPOINT] = PERF_OUTPUT_COMM | PERF_OUTPUT_TID | \ 61 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
62 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME | \ 62 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
63 PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE, 63 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
64
65 .invalid_fields = PERF_OUTPUT_TRACE,
66 },
67
68 [PERF_TYPE_SOFTWARE] = {
69 .user_set = false,
70
71 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
72 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
73 PERF_OUTPUT_EVNAME | PERF_OUTPUT_SYM,
74
75 .invalid_fields = PERF_OUTPUT_TRACE,
76 },
77
78 [PERF_TYPE_TRACEPOINT] = {
79 .user_set = false,
80
81 .fields = PERF_OUTPUT_COMM | PERF_OUTPUT_TID |
82 PERF_OUTPUT_CPU | PERF_OUTPUT_TIME |
83 PERF_OUTPUT_EVNAME | PERF_OUTPUT_TRACE,
84 },
64}; 85};
65 86
66static bool output_set_by_user; 87static bool output_set_by_user(void)
88{
89 int j;
90 for (j = 0; j < PERF_TYPE_MAX; ++j) {
91 if (output[j].user_set)
92 return true;
93 }
94 return false;
95}
67 96
68#define PRINT_FIELD(x) (output_fields[attr->type] & PERF_OUTPUT_##x) 97#define PRINT_FIELD(x) (output[attr->type].fields & PERF_OUTPUT_##x)
69 98
70static int perf_session__check_attr(struct perf_session *session, 99static int perf_session__check_attr(struct perf_session *session,
71 struct perf_event_attr *attr) 100 struct perf_event_attr *attr)
@@ -168,7 +197,7 @@ static void process_event(union perf_event *event __unused,
168{ 197{
169 struct perf_event_attr *attr = &evsel->attr; 198 struct perf_event_attr *attr = &evsel->attr;
170 199
171 if (output_fields[attr->type] == 0) 200 if (output[attr->type].fields == 0)
172 return; 201 return;
173 202
174 if (perf_session__check_attr(session, attr) < 0) 203 if (perf_session__check_attr(session, attr) < 0)
@@ -451,6 +480,7 @@ static int parse_output_fields(const struct option *opt __used,
451{ 480{
452 char *tok; 481 char *tok;
453 int i, imax = sizeof(all_output_options) / sizeof(struct output_option); 482 int i, imax = sizeof(all_output_options) / sizeof(struct output_option);
483 int j;
454 int rc = 0; 484 int rc = 0;
455 char *str = strdup(arg); 485 char *str = strdup(arg);
456 int type = -1; 486 int type = -1;
@@ -458,52 +488,95 @@ static int parse_output_fields(const struct option *opt __used,
458 if (!str) 488 if (!str)
459 return -ENOMEM; 489 return -ENOMEM;
460 490
461 tok = strtok(str, ":"); 491 /* first word can state for which event type the user is specifying
462 if (!tok) { 492 * the fields. If no type exists, the specified fields apply to all
463 fprintf(stderr, 493 * event types found in the file minus the invalid fields for a type.
464 "Invalid field string - not prepended with type.");
465 return -EINVAL;
466 }
467
468 /* first word should state which event type user
469 * is specifying the fields
470 */ 494 */
471 if (!strcmp(tok, "hw")) 495 tok = strchr(str, ':');
472 type = PERF_TYPE_HARDWARE; 496 if (tok) {
473 else if (!strcmp(tok, "sw")) 497 *tok = '\0';
474 type = PERF_TYPE_SOFTWARE; 498 tok++;
475 else if (!strcmp(tok, "trace")) 499 if (!strcmp(str, "hw"))
476 type = PERF_TYPE_TRACEPOINT; 500 type = PERF_TYPE_HARDWARE;
477 else { 501 else if (!strcmp(str, "sw"))
478 fprintf(stderr, "Invalid event type in field string."); 502 type = PERF_TYPE_SOFTWARE;
479 return -EINVAL; 503 else if (!strcmp(str, "trace"))
504 type = PERF_TYPE_TRACEPOINT;
505 else {
506 fprintf(stderr, "Invalid event type in field string.\n");
507 return -EINVAL;
508 }
509
510 if (output[type].user_set)
511 pr_warning("Overriding previous field request for %s events.\n",
512 event_type(type));
513
514 output[type].fields = 0;
515 output[type].user_set = true;
516
517 } else {
518 tok = str;
519 if (strlen(str) == 0) {
520 fprintf(stderr,
521 "Cannot set fields to 'none' for all event types.\n");
522 rc = -EINVAL;
523 goto out;
524 }
525
526 if (output_set_by_user())
527 pr_warning("Overriding previous field request for all events.\n");
528
529 for (j = 0; j < PERF_TYPE_MAX; ++j) {
530 output[j].fields = 0;
531 output[j].user_set = true;
532 }
480 } 533 }
481 534
482 output_fields[type] = 0; 535 tok = strtok(tok, ",");
483 while (1) { 536 while (tok) {
484 tok = strtok(NULL, ",");
485 if (!tok)
486 break;
487 for (i = 0; i < imax; ++i) { 537 for (i = 0; i < imax; ++i) {
488 if (strcmp(tok, all_output_options[i].str) == 0) { 538 if (strcmp(tok, all_output_options[i].str) == 0)
489 output_fields[type] |= all_output_options[i].field;
490 break; 539 break;
491 }
492 } 540 }
493 if (i == imax) { 541 if (i == imax) {
494 fprintf(stderr, "Invalid field requested."); 542 fprintf(stderr, "Invalid field requested.\n");
495 rc = -EINVAL; 543 rc = -EINVAL;
496 break; 544 goto out;
497 } 545 }
498 }
499 546
500 if (output_fields[type] == 0) { 547 if (type == -1) {
501 pr_debug("No fields requested for %s type. " 548 /* add user option to all events types for
502 "Events will not be displayed\n", event_type(type)); 549 * which it is valid
550 */
551 for (j = 0; j < PERF_TYPE_MAX; ++j) {
552 if (output[j].invalid_fields & all_output_options[i].field) {
553 pr_warning("\'%s\' not valid for %s events. Ignoring.\n",
554 all_output_options[i].str, event_type(j));
555 } else
556 output[j].fields |= all_output_options[i].field;
557 }
558 } else {
559 if (output[type].invalid_fields & all_output_options[i].field) {
560 fprintf(stderr, "\'%s\' not valid for %s events.\n",
561 all_output_options[i].str, event_type(type));
562
563 rc = -EINVAL;
564 goto out;
565 }
566 output[type].fields |= all_output_options[i].field;
567 }
568
569 tok = strtok(NULL, ",");
503 } 570 }
504 571
505 output_set_by_user = true; 572 if (type >= 0) {
573 if (output[type].fields == 0) {
574 pr_debug("No fields requested for %s type. "
575 "Events will not be displayed.\n", event_type(type));
576 }
577 }
506 578
579out:
507 free(str); 580 free(str);
508 return rc; 581 return rc;
509} 582}
@@ -1020,7 +1093,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
1020 struct stat perf_stat; 1093 struct stat perf_stat;
1021 int input; 1094 int input;
1022 1095
1023 if (output_set_by_user) { 1096 if (output_set_by_user()) {
1024 fprintf(stderr, 1097 fprintf(stderr,
1025 "custom fields not supported for generated scripts"); 1098 "custom fields not supported for generated scripts");
1026 return -1; 1099 return -1;