diff options
Diffstat (limited to 'tools/perf/util')
-rw-r--r-- | tools/perf/util/evsel.c | 288 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 6 | ||||
-rw-r--r-- | tools/perf/util/header.c | 29 |
3 files changed, 141 insertions, 182 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index d190f99a3a97..33e3fd8c2e68 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -1011,70 +1011,126 @@ static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread) | |||
1011 | return fd; | 1011 | return fd; |
1012 | } | 1012 | } |
1013 | 1013 | ||
1014 | #define __PRINT_ATTR(fmt, cast, field) \ | 1014 | struct bit_names { |
1015 | fprintf(fp, " %-19s "fmt"\n", #field, cast attr->field) | 1015 | int bit; |
1016 | 1016 | const char *name; | |
1017 | #define PRINT_ATTR_U32(field) __PRINT_ATTR("%u" , , field) | 1017 | }; |
1018 | #define PRINT_ATTR_X32(field) __PRINT_ATTR("%#x", , field) | 1018 | |
1019 | #define PRINT_ATTR_U64(field) __PRINT_ATTR("%" PRIu64, (uint64_t), field) | 1019 | static void __p_bits(char *buf, size_t size, u64 value, struct bit_names *bits) |
1020 | #define PRINT_ATTR_X64(field) __PRINT_ATTR("%#"PRIx64, (uint64_t), field) | 1020 | { |
1021 | 1021 | bool first_bit = true; | |
1022 | #define PRINT_ATTR2N(name1, field1, name2, field2) \ | 1022 | int i = 0; |
1023 | fprintf(fp, " %-19s %u %-19s %u\n", \ | 1023 | |
1024 | name1, attr->field1, name2, attr->field2) | 1024 | do { |
1025 | 1025 | if (value & bits[i].bit) { | |
1026 | #define PRINT_ATTR2(field1, field2) \ | 1026 | buf += scnprintf(buf, size, "%s%s", first_bit ? "" : "|", bits[i].name); |
1027 | PRINT_ATTR2N(#field1, field1, #field2, field2) | 1027 | first_bit = false; |
1028 | 1028 | } | |
1029 | static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp) | 1029 | } while (bits[++i].name != NULL); |
1030 | { | 1030 | } |
1031 | size_t ret = 0; | 1031 | |
1032 | 1032 | static void __p_sample_type(char *buf, size_t size, u64 value) | |
1033 | ret += fprintf(fp, "%.60s\n", graph_dotted_line); | 1033 | { |
1034 | ret += fprintf(fp, "perf_event_attr:\n"); | 1034 | #define bit_name(n) { PERF_SAMPLE_##n, #n } |
1035 | 1035 | struct bit_names bits[] = { | |
1036 | ret += PRINT_ATTR_U32(type); | 1036 | bit_name(IP), bit_name(TID), bit_name(TIME), bit_name(ADDR), |
1037 | ret += PRINT_ATTR_U32(size); | 1037 | bit_name(READ), bit_name(CALLCHAIN), bit_name(ID), bit_name(CPU), |
1038 | ret += PRINT_ATTR_X64(config); | 1038 | bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW), |
1039 | ret += PRINT_ATTR_U64(sample_period); | 1039 | bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER), |
1040 | ret += PRINT_ATTR_U64(sample_freq); | 1040 | bit_name(IDENTIFIER), bit_name(REGS_INTR), |
1041 | ret += PRINT_ATTR_X64(sample_type); | 1041 | { .name = NULL, } |
1042 | ret += PRINT_ATTR_X64(read_format); | 1042 | }; |
1043 | 1043 | #undef bit_name | |
1044 | ret += PRINT_ATTR2(disabled, inherit); | 1044 | __p_bits(buf, size, value, bits); |
1045 | ret += PRINT_ATTR2(pinned, exclusive); | 1045 | } |
1046 | ret += PRINT_ATTR2(exclude_user, exclude_kernel); | 1046 | |
1047 | ret += PRINT_ATTR2(exclude_hv, exclude_idle); | 1047 | static void __p_read_format(char *buf, size_t size, u64 value) |
1048 | ret += PRINT_ATTR2(mmap, comm); | 1048 | { |
1049 | ret += PRINT_ATTR2(freq, inherit_stat); | 1049 | #define bit_name(n) { PERF_FORMAT_##n, #n } |
1050 | ret += PRINT_ATTR2(enable_on_exec, task); | 1050 | struct bit_names bits[] = { |
1051 | ret += PRINT_ATTR2(watermark, precise_ip); | 1051 | bit_name(TOTAL_TIME_ENABLED), bit_name(TOTAL_TIME_RUNNING), |
1052 | ret += PRINT_ATTR2(mmap_data, sample_id_all); | 1052 | bit_name(ID), bit_name(GROUP), |
1053 | ret += PRINT_ATTR2(exclude_host, exclude_guest); | 1053 | { .name = NULL, } |
1054 | ret += PRINT_ATTR2N("excl.callchain_kern", exclude_callchain_kernel, | 1054 | }; |
1055 | "excl.callchain_user", exclude_callchain_user); | 1055 | #undef bit_name |
1056 | ret += PRINT_ATTR2(mmap2, comm_exec); | 1056 | __p_bits(buf, size, value, bits); |
1057 | ret += __PRINT_ATTR("%u",,use_clockid); | 1057 | } |
1058 | 1058 | ||
1059 | 1059 | #define BUF_SIZE 1024 | |
1060 | ret += PRINT_ATTR_U32(wakeup_events); | 1060 | |
1061 | ret += PRINT_ATTR_U32(wakeup_watermark); | 1061 | #define p_hex(val) snprintf(buf, BUF_SIZE, "%"PRIx64, (uint64_t)(val)) |
1062 | ret += PRINT_ATTR_X32(bp_type); | 1062 | #define p_unsigned(val) snprintf(buf, BUF_SIZE, "%"PRIu64, (uint64_t)(val)) |
1063 | ret += PRINT_ATTR_X64(bp_addr); | 1063 | #define p_signed(val) snprintf(buf, BUF_SIZE, "%"PRId64, (int64_t)(val)) |
1064 | ret += PRINT_ATTR_X64(config1); | 1064 | #define p_sample_type(val) __p_sample_type(buf, BUF_SIZE, val) |
1065 | ret += PRINT_ATTR_U64(bp_len); | 1065 | #define p_read_format(val) __p_read_format(buf, BUF_SIZE, val) |
1066 | ret += PRINT_ATTR_X64(config2); | 1066 | |
1067 | ret += PRINT_ATTR_X64(branch_sample_type); | 1067 | #define PRINT_ATTRn(_n, _f, _p) \ |
1068 | ret += PRINT_ATTR_X64(sample_regs_user); | 1068 | do { \ |
1069 | ret += PRINT_ATTR_U32(sample_stack_user); | 1069 | if (attr->_f) { \ |
1070 | ret += PRINT_ATTR_U32(clockid); | 1070 | _p(attr->_f); \ |
1071 | ret += PRINT_ATTR_X64(sample_regs_intr); | 1071 | ret += attr__fprintf(fp, _n, buf, priv);\ |
1072 | 1072 | } \ | |
1073 | ret += fprintf(fp, "%.60s\n", graph_dotted_line); | 1073 | } while (0) |
1074 | |||
1075 | #define PRINT_ATTRf(_f, _p) PRINT_ATTRn(#_f, _f, _p) | ||
1076 | |||
1077 | int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, | ||
1078 | attr__fprintf_f attr__fprintf, void *priv) | ||
1079 | { | ||
1080 | char buf[BUF_SIZE]; | ||
1081 | int ret = 0; | ||
1082 | |||
1083 | PRINT_ATTRf(type, p_unsigned); | ||
1084 | PRINT_ATTRf(size, p_unsigned); | ||
1085 | PRINT_ATTRf(config, p_hex); | ||
1086 | PRINT_ATTRn("{ sample_period, sample_freq }", sample_period, p_unsigned); | ||
1087 | PRINT_ATTRf(sample_type, p_sample_type); | ||
1088 | PRINT_ATTRf(read_format, p_read_format); | ||
1089 | |||
1090 | PRINT_ATTRf(disabled, p_unsigned); | ||
1091 | PRINT_ATTRf(inherit, p_unsigned); | ||
1092 | PRINT_ATTRf(pinned, p_unsigned); | ||
1093 | PRINT_ATTRf(exclusive, p_unsigned); | ||
1094 | PRINT_ATTRf(exclude_user, p_unsigned); | ||
1095 | PRINT_ATTRf(exclude_kernel, p_unsigned); | ||
1096 | PRINT_ATTRf(exclude_hv, p_unsigned); | ||
1097 | PRINT_ATTRf(exclude_idle, p_unsigned); | ||
1098 | PRINT_ATTRf(mmap, p_unsigned); | ||
1099 | PRINT_ATTRf(comm, p_unsigned); | ||
1100 | PRINT_ATTRf(freq, p_unsigned); | ||
1101 | PRINT_ATTRf(inherit_stat, p_unsigned); | ||
1102 | PRINT_ATTRf(enable_on_exec, p_unsigned); | ||
1103 | PRINT_ATTRf(task, p_unsigned); | ||
1104 | PRINT_ATTRf(watermark, p_unsigned); | ||
1105 | PRINT_ATTRf(precise_ip, p_unsigned); | ||
1106 | PRINT_ATTRf(mmap_data, p_unsigned); | ||
1107 | PRINT_ATTRf(sample_id_all, p_unsigned); | ||
1108 | PRINT_ATTRf(exclude_host, p_unsigned); | ||
1109 | PRINT_ATTRf(exclude_guest, p_unsigned); | ||
1110 | PRINT_ATTRf(exclude_callchain_kernel, p_unsigned); | ||
1111 | PRINT_ATTRf(exclude_callchain_user, p_unsigned); | ||
1112 | PRINT_ATTRf(mmap2, p_unsigned); | ||
1113 | PRINT_ATTRf(comm_exec, p_unsigned); | ||
1114 | PRINT_ATTRf(use_clockid, p_unsigned); | ||
1115 | |||
1116 | PRINT_ATTRn("{ wakeup_events, wakeup_watermark }", wakeup_events, p_unsigned); | ||
1117 | PRINT_ATTRf(bp_type, p_unsigned); | ||
1118 | PRINT_ATTRn("{ bp_addr, config1 }", bp_addr, p_hex); | ||
1119 | PRINT_ATTRn("{ bp_len, config2 }", bp_len, p_hex); | ||
1120 | PRINT_ATTRf(sample_regs_user, p_hex); | ||
1121 | PRINT_ATTRf(sample_stack_user, p_unsigned); | ||
1122 | PRINT_ATTRf(clockid, p_signed); | ||
1123 | PRINT_ATTRf(sample_regs_intr, p_hex); | ||
1074 | 1124 | ||
1075 | return ret; | 1125 | return ret; |
1076 | } | 1126 | } |
1077 | 1127 | ||
1128 | static int __open_attr__fprintf(FILE *fp, const char *name, const char *val, | ||
1129 | void *priv __attribute__((unused))) | ||
1130 | { | ||
1131 | return fprintf(fp, " %-32s %s\n", name, val); | ||
1132 | } | ||
1133 | |||
1078 | static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | 1134 | static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, |
1079 | struct thread_map *threads) | 1135 | struct thread_map *threads) |
1080 | { | 1136 | { |
@@ -1114,8 +1170,12 @@ retry_sample_id: | |||
1114 | if (perf_missing_features.sample_id_all) | 1170 | if (perf_missing_features.sample_id_all) |
1115 | evsel->attr.sample_id_all = 0; | 1171 | evsel->attr.sample_id_all = 0; |
1116 | 1172 | ||
1117 | if (verbose >= 2) | 1173 | if (verbose >= 2) { |
1118 | perf_event_attr__fprintf(&evsel->attr, stderr); | 1174 | fprintf(stderr, "%.60s\n", graph_dotted_line); |
1175 | fprintf(stderr, "perf_event_attr:\n"); | ||
1176 | perf_event_attr__fprintf(stderr, &evsel->attr, __open_attr__fprintf, NULL); | ||
1177 | fprintf(stderr, "%.60s\n", graph_dotted_line); | ||
1178 | } | ||
1119 | 1179 | ||
1120 | for (cpu = 0; cpu < cpus->nr; cpu++) { | 1180 | for (cpu = 0; cpu < cpus->nr; cpu++) { |
1121 | 1181 | ||
@@ -1996,62 +2056,9 @@ static int comma_fprintf(FILE *fp, bool *first, const char *fmt, ...) | |||
1996 | return ret; | 2056 | return ret; |
1997 | } | 2057 | } |
1998 | 2058 | ||
1999 | static int __if_fprintf(FILE *fp, bool *first, const char *field, u64 value) | 2059 | static int __print_attr__fprintf(FILE *fp, const char *name, const char *val, void *priv) |
2000 | { | ||
2001 | if (value == 0) | ||
2002 | return 0; | ||
2003 | |||
2004 | return comma_fprintf(fp, first, " %s: %" PRIu64, field, value); | ||
2005 | } | ||
2006 | |||
2007 | #define if_print(field) printed += __if_fprintf(fp, &first, #field, evsel->attr.field) | ||
2008 | |||
2009 | struct bit_names { | ||
2010 | int bit; | ||
2011 | const char *name; | ||
2012 | }; | ||
2013 | |||
2014 | static int bits__fprintf(FILE *fp, const char *field, u64 value, | ||
2015 | struct bit_names *bits, bool *first) | ||
2016 | { | 2060 | { |
2017 | int i = 0, printed = comma_fprintf(fp, first, " %s: ", field); | 2061 | return comma_fprintf(fp, (bool *)priv, " %s: %s", name, val); |
2018 | bool first_bit = true; | ||
2019 | |||
2020 | do { | ||
2021 | if (value & bits[i].bit) { | ||
2022 | printed += fprintf(fp, "%s%s", first_bit ? "" : "|", bits[i].name); | ||
2023 | first_bit = false; | ||
2024 | } | ||
2025 | } while (bits[++i].name != NULL); | ||
2026 | |||
2027 | return printed; | ||
2028 | } | ||
2029 | |||
2030 | static int sample_type__fprintf(FILE *fp, bool *first, u64 value) | ||
2031 | { | ||
2032 | #define bit_name(n) { PERF_SAMPLE_##n, #n } | ||
2033 | struct bit_names bits[] = { | ||
2034 | bit_name(IP), bit_name(TID), bit_name(TIME), bit_name(ADDR), | ||
2035 | bit_name(READ), bit_name(CALLCHAIN), bit_name(ID), bit_name(CPU), | ||
2036 | bit_name(PERIOD), bit_name(STREAM_ID), bit_name(RAW), | ||
2037 | bit_name(BRANCH_STACK), bit_name(REGS_USER), bit_name(STACK_USER), | ||
2038 | bit_name(IDENTIFIER), bit_name(REGS_INTR), | ||
2039 | { .name = NULL, } | ||
2040 | }; | ||
2041 | #undef bit_name | ||
2042 | return bits__fprintf(fp, "sample_type", value, bits, first); | ||
2043 | } | ||
2044 | |||
2045 | static int read_format__fprintf(FILE *fp, bool *first, u64 value) | ||
2046 | { | ||
2047 | #define bit_name(n) { PERF_FORMAT_##n, #n } | ||
2048 | struct bit_names bits[] = { | ||
2049 | bit_name(TOTAL_TIME_ENABLED), bit_name(TOTAL_TIME_RUNNING), | ||
2050 | bit_name(ID), bit_name(GROUP), | ||
2051 | { .name = NULL, } | ||
2052 | }; | ||
2053 | #undef bit_name | ||
2054 | return bits__fprintf(fp, "read_format", value, bits, first); | ||
2055 | } | 2062 | } |
2056 | 2063 | ||
2057 | int perf_evsel__fprintf(struct perf_evsel *evsel, | 2064 | int perf_evsel__fprintf(struct perf_evsel *evsel, |
@@ -2080,52 +2087,13 @@ int perf_evsel__fprintf(struct perf_evsel *evsel, | |||
2080 | 2087 | ||
2081 | printed += fprintf(fp, "%s", perf_evsel__name(evsel)); | 2088 | printed += fprintf(fp, "%s", perf_evsel__name(evsel)); |
2082 | 2089 | ||
2083 | if (details->verbose || details->freq) { | 2090 | if (details->verbose) { |
2091 | printed += perf_event_attr__fprintf(fp, &evsel->attr, | ||
2092 | __print_attr__fprintf, &first); | ||
2093 | } else if (details->freq) { | ||
2084 | printed += comma_fprintf(fp, &first, " sample_freq=%" PRIu64, | 2094 | printed += comma_fprintf(fp, &first, " sample_freq=%" PRIu64, |
2085 | (u64)evsel->attr.sample_freq); | 2095 | (u64)evsel->attr.sample_freq); |
2086 | } | 2096 | } |
2087 | |||
2088 | if (details->verbose) { | ||
2089 | if_print(type); | ||
2090 | if_print(config); | ||
2091 | if_print(config1); | ||
2092 | if_print(config2); | ||
2093 | if_print(size); | ||
2094 | printed += sample_type__fprintf(fp, &first, evsel->attr.sample_type); | ||
2095 | if (evsel->attr.read_format) | ||
2096 | printed += read_format__fprintf(fp, &first, evsel->attr.read_format); | ||
2097 | if_print(disabled); | ||
2098 | if_print(inherit); | ||
2099 | if_print(pinned); | ||
2100 | if_print(exclusive); | ||
2101 | if_print(exclude_user); | ||
2102 | if_print(exclude_kernel); | ||
2103 | if_print(exclude_hv); | ||
2104 | if_print(exclude_idle); | ||
2105 | if_print(mmap); | ||
2106 | if_print(comm); | ||
2107 | if_print(freq); | ||
2108 | if_print(inherit_stat); | ||
2109 | if_print(enable_on_exec); | ||
2110 | if_print(task); | ||
2111 | if_print(watermark); | ||
2112 | if_print(precise_ip); | ||
2113 | if_print(mmap_data); | ||
2114 | if_print(sample_id_all); | ||
2115 | if_print(exclude_host); | ||
2116 | if_print(exclude_guest); | ||
2117 | if_print(mmap2); | ||
2118 | if_print(comm_exec); | ||
2119 | if_print(use_clockid); | ||
2120 | if_print(__reserved_1); | ||
2121 | if_print(wakeup_events); | ||
2122 | if_print(bp_type); | ||
2123 | if_print(branch_sample_type); | ||
2124 | if_print(sample_regs_user); | ||
2125 | if_print(sample_stack_user); | ||
2126 | if_print(clockid); | ||
2127 | if_print(sample_regs_intr); | ||
2128 | } | ||
2129 | out: | 2097 | out: |
2130 | fputc('\n', fp); | 2098 | fputc('\n', fp); |
2131 | return ++printed; | 2099 | return ++printed; |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index c5a43d6b13dc..e486151b0308 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -360,4 +360,10 @@ static inline bool has_branch_callstack(struct perf_evsel *evsel) | |||
360 | { | 360 | { |
361 | return evsel->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK; | 361 | return evsel->attr.branch_sample_type & PERF_SAMPLE_BRANCH_CALL_STACK; |
362 | } | 362 | } |
363 | |||
364 | typedef int (*attr__fprintf_f)(FILE *, const char *, const char *, void *); | ||
365 | |||
366 | int perf_event_attr__fprintf(FILE *fp, struct perf_event_attr *attr, | ||
367 | attr__fprintf_f attr__fprintf, void *priv); | ||
368 | |||
363 | #endif /* __PERF_EVSEL_H */ | 369 | #endif /* __PERF_EVSEL_H */ |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index de5f4669ba5f..fff3b2a455ae 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -1055,6 +1055,12 @@ error: | |||
1055 | goto out; | 1055 | goto out; |
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | static int __desc_attr__fprintf(FILE *fp, const char *name, const char *val, | ||
1059 | void *priv __attribute__((unused))) | ||
1060 | { | ||
1061 | return fprintf(fp, ", %s = %s", name, val); | ||
1062 | } | ||
1063 | |||
1058 | static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) | 1064 | static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) |
1059 | { | 1065 | { |
1060 | struct perf_evsel *evsel, *events = read_event_desc(ph, fd); | 1066 | struct perf_evsel *evsel, *events = read_event_desc(ph, fd); |
@@ -1069,26 +1075,6 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) | |||
1069 | for (evsel = events; evsel->attr.size; evsel++) { | 1075 | for (evsel = events; evsel->attr.size; evsel++) { |
1070 | fprintf(fp, "# event : name = %s, ", evsel->name); | 1076 | fprintf(fp, "# event : name = %s, ", evsel->name); |
1071 | 1077 | ||
1072 | fprintf(fp, "type = %d, config = 0x%"PRIx64 | ||
1073 | ", config1 = 0x%"PRIx64", config2 = 0x%"PRIx64, | ||
1074 | evsel->attr.type, | ||
1075 | (u64)evsel->attr.config, | ||
1076 | (u64)evsel->attr.config1, | ||
1077 | (u64)evsel->attr.config2); | ||
1078 | |||
1079 | fprintf(fp, ", excl_usr = %d, excl_kern = %d", | ||
1080 | evsel->attr.exclude_user, | ||
1081 | evsel->attr.exclude_kernel); | ||
1082 | |||
1083 | fprintf(fp, ", excl_host = %d, excl_guest = %d", | ||
1084 | evsel->attr.exclude_host, | ||
1085 | evsel->attr.exclude_guest); | ||
1086 | |||
1087 | fprintf(fp, ", precise_ip = %d", evsel->attr.precise_ip); | ||
1088 | |||
1089 | fprintf(fp, ", attr_mmap2 = %d", evsel->attr.mmap2); | ||
1090 | fprintf(fp, ", attr_mmap = %d", evsel->attr.mmap); | ||
1091 | fprintf(fp, ", attr_mmap_data = %d", evsel->attr.mmap_data); | ||
1092 | if (evsel->ids) { | 1078 | if (evsel->ids) { |
1093 | fprintf(fp, ", id = {"); | 1079 | fprintf(fp, ", id = {"); |
1094 | for (j = 0, id = evsel->id; j < evsel->ids; j++, id++) { | 1080 | for (j = 0, id = evsel->id; j < evsel->ids; j++, id++) { |
@@ -1098,9 +1084,8 @@ static void print_event_desc(struct perf_header *ph, int fd, FILE *fp) | |||
1098 | } | 1084 | } |
1099 | fprintf(fp, " }"); | 1085 | fprintf(fp, " }"); |
1100 | } | 1086 | } |
1101 | if (evsel->attr.use_clockid) | ||
1102 | fprintf(fp, ", clockid = %d", evsel->attr.clockid); | ||
1103 | 1087 | ||
1088 | perf_event_attr__fprintf(fp, &evsel->attr, __desc_attr__fprintf, NULL); | ||
1104 | 1089 | ||
1105 | fputc('\n', fp); | 1090 | fputc('\n', fp); |
1106 | } | 1091 | } |