diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-07-27 03:54:47 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-07-27 03:54:47 -0400 |
| commit | aa7eb8e78d8ecd6cd0475d86ea8385ff9cb47ece (patch) | |
| tree | 3f9e98fadd5124fb05e8f6f9b06aa23698d4f215 /tools/perf/util/parse-events.c | |
| parent | cca8edfd2ec2a34d9f50f593bc753bb11e1bc1f5 (diff) | |
| parent | 3c6b50141ef9f0a8844bf1357b80c0cdf518bf05 (diff) | |
Merge branch 'next' into for-linus
Diffstat (limited to 'tools/perf/util/parse-events.c')
| -rw-r--r-- | tools/perf/util/parse-events.c | 123 |
1 files changed, 72 insertions, 51 deletions
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 952b4ae3d954..41982c373faf 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
| @@ -31,34 +31,36 @@ char debugfs_path[MAXPATHLEN]; | |||
| 31 | #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x | 31 | #define CSW(x) .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_##x |
| 32 | 32 | ||
| 33 | static struct event_symbol event_symbols[] = { | 33 | static struct event_symbol event_symbols[] = { |
| 34 | { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, | 34 | { CHW(CPU_CYCLES), "cpu-cycles", "cycles" }, |
| 35 | { CHW(INSTRUCTIONS), "instructions", "" }, | 35 | { CHW(STALLED_CYCLES_FRONTEND), "stalled-cycles-frontend", "idle-cycles-frontend" }, |
| 36 | { CHW(CACHE_REFERENCES), "cache-references", "" }, | 36 | { CHW(STALLED_CYCLES_BACKEND), "stalled-cycles-backend", "idle-cycles-backend" }, |
| 37 | { CHW(CACHE_MISSES), "cache-misses", "" }, | 37 | { CHW(INSTRUCTIONS), "instructions", "" }, |
| 38 | { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, | 38 | { CHW(CACHE_REFERENCES), "cache-references", "" }, |
| 39 | { CHW(BRANCH_MISSES), "branch-misses", "" }, | 39 | { CHW(CACHE_MISSES), "cache-misses", "" }, |
| 40 | { CHW(BUS_CYCLES), "bus-cycles", "" }, | 40 | { CHW(BRANCH_INSTRUCTIONS), "branch-instructions", "branches" }, |
| 41 | 41 | { CHW(BRANCH_MISSES), "branch-misses", "" }, | |
| 42 | { CSW(CPU_CLOCK), "cpu-clock", "" }, | 42 | { CHW(BUS_CYCLES), "bus-cycles", "" }, |
| 43 | { CSW(TASK_CLOCK), "task-clock", "" }, | 43 | |
| 44 | { CSW(PAGE_FAULTS), "page-faults", "faults" }, | 44 | { CSW(CPU_CLOCK), "cpu-clock", "" }, |
| 45 | { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, | 45 | { CSW(TASK_CLOCK), "task-clock", "" }, |
| 46 | { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, | 46 | { CSW(PAGE_FAULTS), "page-faults", "faults" }, |
| 47 | { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, | 47 | { CSW(PAGE_FAULTS_MIN), "minor-faults", "" }, |
| 48 | { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, | 48 | { CSW(PAGE_FAULTS_MAJ), "major-faults", "" }, |
| 49 | { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" }, | 49 | { CSW(CONTEXT_SWITCHES), "context-switches", "cs" }, |
| 50 | { CSW(EMULATION_FAULTS), "emulation-faults", "" }, | 50 | { CSW(CPU_MIGRATIONS), "cpu-migrations", "migrations" }, |
| 51 | { CSW(ALIGNMENT_FAULTS), "alignment-faults", "" }, | ||
| 52 | { CSW(EMULATION_FAULTS), "emulation-faults", "" }, | ||
| 51 | }; | 53 | }; |
| 52 | 54 | ||
| 53 | #define __PERF_EVENT_FIELD(config, name) \ | 55 | #define __PERF_EVENT_FIELD(config, name) \ |
| 54 | ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) | 56 | ((config & PERF_EVENT_##name##_MASK) >> PERF_EVENT_##name##_SHIFT) |
| 55 | 57 | ||
| 56 | #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) | 58 | #define PERF_EVENT_RAW(config) __PERF_EVENT_FIELD(config, RAW) |
| 57 | #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) | 59 | #define PERF_EVENT_CONFIG(config) __PERF_EVENT_FIELD(config, CONFIG) |
| 58 | #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) | 60 | #define PERF_EVENT_TYPE(config) __PERF_EVENT_FIELD(config, TYPE) |
| 59 | #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) | 61 | #define PERF_EVENT_ID(config) __PERF_EVENT_FIELD(config, EVENT) |
| 60 | 62 | ||
| 61 | static const char *hw_event_names[] = { | 63 | static const char *hw_event_names[PERF_COUNT_HW_MAX] = { |
| 62 | "cycles", | 64 | "cycles", |
| 63 | "instructions", | 65 | "instructions", |
| 64 | "cache-references", | 66 | "cache-references", |
| @@ -66,11 +68,13 @@ static const char *hw_event_names[] = { | |||
| 66 | "branches", | 68 | "branches", |
| 67 | "branch-misses", | 69 | "branch-misses", |
| 68 | "bus-cycles", | 70 | "bus-cycles", |
| 71 | "stalled-cycles-frontend", | ||
| 72 | "stalled-cycles-backend", | ||
| 69 | }; | 73 | }; |
| 70 | 74 | ||
| 71 | static const char *sw_event_names[] = { | 75 | static const char *sw_event_names[PERF_COUNT_SW_MAX] = { |
| 72 | "cpu-clock-msecs", | 76 | "cpu-clock", |
| 73 | "task-clock-msecs", | 77 | "task-clock", |
| 74 | "page-faults", | 78 | "page-faults", |
| 75 | "context-switches", | 79 | "context-switches", |
| 76 | "CPU-migrations", | 80 | "CPU-migrations", |
| @@ -307,7 +311,7 @@ const char *__event_name(int type, u64 config) | |||
| 307 | 311 | ||
| 308 | switch (type) { | 312 | switch (type) { |
| 309 | case PERF_TYPE_HARDWARE: | 313 | case PERF_TYPE_HARDWARE: |
| 310 | if (config < PERF_COUNT_HW_MAX) | 314 | if (config < PERF_COUNT_HW_MAX && hw_event_names[config]) |
| 311 | return hw_event_names[config]; | 315 | return hw_event_names[config]; |
| 312 | return "unknown-hardware"; | 316 | return "unknown-hardware"; |
| 313 | 317 | ||
| @@ -333,7 +337,7 @@ const char *__event_name(int type, u64 config) | |||
| 333 | } | 337 | } |
| 334 | 338 | ||
| 335 | case PERF_TYPE_SOFTWARE: | 339 | case PERF_TYPE_SOFTWARE: |
| 336 | if (config < PERF_COUNT_SW_MAX) | 340 | if (config < PERF_COUNT_SW_MAX && sw_event_names[config]) |
| 337 | return sw_event_names[config]; | 341 | return sw_event_names[config]; |
| 338 | return "unknown-software"; | 342 | return "unknown-software"; |
| 339 | 343 | ||
| @@ -648,13 +652,15 @@ static int check_events(const char *str, unsigned int i) | |||
| 648 | int n; | 652 | int n; |
| 649 | 653 | ||
| 650 | n = strlen(event_symbols[i].symbol); | 654 | n = strlen(event_symbols[i].symbol); |
| 651 | if (!strncmp(str, event_symbols[i].symbol, n)) | 655 | if (!strncasecmp(str, event_symbols[i].symbol, n)) |
| 652 | return n; | 656 | return n; |
| 653 | 657 | ||
| 654 | n = strlen(event_symbols[i].alias); | 658 | n = strlen(event_symbols[i].alias); |
| 655 | if (n) | 659 | if (n) { |
| 656 | if (!strncmp(str, event_symbols[i].alias, n)) | 660 | if (!strncasecmp(str, event_symbols[i].alias, n)) |
| 657 | return n; | 661 | return n; |
| 662 | } | ||
| 663 | |||
| 658 | return 0; | 664 | return 0; |
| 659 | } | 665 | } |
| 660 | 666 | ||
| @@ -718,15 +724,22 @@ parse_numeric_event(const char **strp, struct perf_event_attr *attr) | |||
| 718 | return EVT_FAILED; | 724 | return EVT_FAILED; |
| 719 | } | 725 | } |
| 720 | 726 | ||
| 721 | static enum event_result | 727 | static int |
| 722 | parse_event_modifier(const char **strp, struct perf_event_attr *attr) | 728 | parse_event_modifier(const char **strp, struct perf_event_attr *attr) |
| 723 | { | 729 | { |
| 724 | const char *str = *strp; | 730 | const char *str = *strp; |
| 725 | int exclude = 0; | 731 | int exclude = 0; |
| 726 | int eu = 0, ek = 0, eh = 0, precise = 0; | 732 | int eu = 0, ek = 0, eh = 0, precise = 0; |
| 727 | 733 | ||
| 728 | if (*str++ != ':') | 734 | if (!*str) |
| 735 | return 0; | ||
| 736 | |||
| 737 | if (*str == ',') | ||
| 729 | return 0; | 738 | return 0; |
| 739 | |||
| 740 | if (*str++ != ':') | ||
| 741 | return -1; | ||
| 742 | |||
| 730 | while (*str) { | 743 | while (*str) { |
| 731 | if (*str == 'u') { | 744 | if (*str == 'u') { |
| 732 | if (!exclude) | 745 | if (!exclude) |
| @@ -747,14 +760,16 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr) | |||
| 747 | 760 | ||
| 748 | ++str; | 761 | ++str; |
| 749 | } | 762 | } |
| 750 | if (str >= *strp + 2) { | 763 | if (str < *strp + 2) |
| 751 | *strp = str; | 764 | return -1; |
| 752 | attr->exclude_user = eu; | 765 | |
| 753 | attr->exclude_kernel = ek; | 766 | *strp = str; |
| 754 | attr->exclude_hv = eh; | 767 | |
| 755 | attr->precise_ip = precise; | 768 | attr->exclude_user = eu; |
| 756 | return 1; | 769 | attr->exclude_kernel = ek; |
| 757 | } | 770 | attr->exclude_hv = eh; |
| 771 | attr->precise_ip = precise; | ||
| 772 | |||
| 758 | return 0; | 773 | return 0; |
| 759 | } | 774 | } |
| 760 | 775 | ||
| @@ -797,7 +812,12 @@ parse_event_symbols(const struct option *opt, const char **str, | |||
| 797 | return EVT_FAILED; | 812 | return EVT_FAILED; |
| 798 | 813 | ||
| 799 | modifier: | 814 | modifier: |
| 800 | parse_event_modifier(str, attr); | 815 | if (parse_event_modifier(str, attr) < 0) { |
| 816 | fprintf(stderr, "invalid event modifier: '%s'\n", *str); | ||
| 817 | fprintf(stderr, "Run 'perf list' for a list of valid events and modifiers\n"); | ||
| 818 | |||
| 819 | return EVT_FAILED; | ||
| 820 | } | ||
| 801 | 821 | ||
| 802 | return ret; | 822 | return ret; |
| 803 | } | 823 | } |
| @@ -912,7 +932,7 @@ void print_tracepoint_events(const char *subsys_glob, const char *event_glob) | |||
| 912 | 932 | ||
| 913 | snprintf(evt_path, MAXPATHLEN, "%s:%s", | 933 | snprintf(evt_path, MAXPATHLEN, "%s:%s", |
| 914 | sys_dirent.d_name, evt_dirent.d_name); | 934 | sys_dirent.d_name, evt_dirent.d_name); |
| 915 | printf(" %-42s [%s]\n", evt_path, | 935 | printf(" %-50s [%s]\n", evt_path, |
| 916 | event_type_descriptors[PERF_TYPE_TRACEPOINT]); | 936 | event_type_descriptors[PERF_TYPE_TRACEPOINT]); |
| 917 | } | 937 | } |
| 918 | closedir(evt_dir); | 938 | closedir(evt_dir); |
| @@ -977,7 +997,7 @@ void print_events_type(u8 type) | |||
| 977 | else | 997 | else |
| 978 | snprintf(name, sizeof(name), "%s", syms->symbol); | 998 | snprintf(name, sizeof(name), "%s", syms->symbol); |
| 979 | 999 | ||
| 980 | printf(" %-42s [%s]\n", name, | 1000 | printf(" %-50s [%s]\n", name, |
| 981 | event_type_descriptors[type]); | 1001 | event_type_descriptors[type]); |
| 982 | } | 1002 | } |
| 983 | } | 1003 | } |
| @@ -995,11 +1015,10 @@ int print_hwcache_events(const char *event_glob) | |||
| 995 | for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { | 1015 | for (i = 0; i < PERF_COUNT_HW_CACHE_RESULT_MAX; i++) { |
| 996 | char *name = event_cache_name(type, op, i); | 1016 | char *name = event_cache_name(type, op, i); |
| 997 | 1017 | ||
| 998 | if (event_glob != NULL && | 1018 | if (event_glob != NULL && !strglobmatch(name, event_glob)) |
| 999 | !strglobmatch(name, event_glob)) | ||
| 1000 | continue; | 1019 | continue; |
| 1001 | 1020 | ||
| 1002 | printf(" %-42s [%s]\n", name, | 1021 | printf(" %-50s [%s]\n", name, |
| 1003 | event_type_descriptors[PERF_TYPE_HW_CACHE]); | 1022 | event_type_descriptors[PERF_TYPE_HW_CACHE]); |
| 1004 | ++printed; | 1023 | ++printed; |
| 1005 | } | 1024 | } |
| @@ -1009,14 +1028,16 @@ int print_hwcache_events(const char *event_glob) | |||
| 1009 | return printed; | 1028 | return printed; |
| 1010 | } | 1029 | } |
| 1011 | 1030 | ||
| 1031 | #define MAX_NAME_LEN 100 | ||
| 1032 | |||
| 1012 | /* | 1033 | /* |
| 1013 | * Print the help text for the event symbols: | 1034 | * Print the help text for the event symbols: |
| 1014 | */ | 1035 | */ |
| 1015 | void print_events(const char *event_glob) | 1036 | void print_events(const char *event_glob) |
| 1016 | { | 1037 | { |
| 1017 | struct event_symbol *syms = event_symbols; | ||
| 1018 | unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0; | 1038 | unsigned int i, type, prev_type = -1, printed = 0, ntypes_printed = 0; |
| 1019 | char name[40]; | 1039 | struct event_symbol *syms = event_symbols; |
| 1040 | char name[MAX_NAME_LEN]; | ||
| 1020 | 1041 | ||
| 1021 | printf("\n"); | 1042 | printf("\n"); |
| 1022 | printf("List of pre-defined events (to be used in -e):\n"); | 1043 | printf("List of pre-defined events (to be used in -e):\n"); |
| @@ -1036,10 +1057,10 @@ void print_events(const char *event_glob) | |||
| 1036 | continue; | 1057 | continue; |
| 1037 | 1058 | ||
| 1038 | if (strlen(syms->alias)) | 1059 | if (strlen(syms->alias)) |
| 1039 | sprintf(name, "%s OR %s", syms->symbol, syms->alias); | 1060 | snprintf(name, MAX_NAME_LEN, "%s OR %s", syms->symbol, syms->alias); |
| 1040 | else | 1061 | else |
| 1041 | strcpy(name, syms->symbol); | 1062 | strncpy(name, syms->symbol, MAX_NAME_LEN); |
| 1042 | printf(" %-42s [%s]\n", name, | 1063 | printf(" %-50s [%s]\n", name, |
| 1043 | event_type_descriptors[type]); | 1064 | event_type_descriptors[type]); |
| 1044 | 1065 | ||
| 1045 | prev_type = type; | 1066 | prev_type = type; |
| @@ -1056,12 +1077,12 @@ void print_events(const char *event_glob) | |||
| 1056 | return; | 1077 | return; |
| 1057 | 1078 | ||
| 1058 | printf("\n"); | 1079 | printf("\n"); |
| 1059 | printf(" %-42s [%s]\n", | 1080 | printf(" %-50s [%s]\n", |
| 1060 | "rNNN (see 'perf list --help' on how to encode it)", | 1081 | "rNNN (see 'perf list --help' on how to encode it)", |
| 1061 | event_type_descriptors[PERF_TYPE_RAW]); | 1082 | event_type_descriptors[PERF_TYPE_RAW]); |
| 1062 | printf("\n"); | 1083 | printf("\n"); |
| 1063 | 1084 | ||
| 1064 | printf(" %-42s [%s]\n", | 1085 | printf(" %-50s [%s]\n", |
| 1065 | "mem:<addr>[:access]", | 1086 | "mem:<addr>[:access]", |
| 1066 | event_type_descriptors[PERF_TYPE_BREAKPOINT]); | 1087 | event_type_descriptors[PERF_TYPE_BREAKPOINT]); |
| 1067 | printf("\n"); | 1088 | printf("\n"); |
