diff options
Diffstat (limited to 'tools/perf/util/evsel.c')
-rw-r--r-- | tools/perf/util/evsel.c | 59 |
1 files changed, 55 insertions, 4 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 358e5954baa8..d190f99a3a97 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -32,8 +32,12 @@ static struct { | |||
32 | bool exclude_guest; | 32 | bool exclude_guest; |
33 | bool mmap2; | 33 | bool mmap2; |
34 | bool cloexec; | 34 | bool cloexec; |
35 | bool clockid; | ||
36 | bool clockid_wrong; | ||
35 | } perf_missing_features; | 37 | } perf_missing_features; |
36 | 38 | ||
39 | static clockid_t clockid; | ||
40 | |||
37 | static int perf_evsel__no_extra_init(struct perf_evsel *evsel __maybe_unused) | 41 | static int perf_evsel__no_extra_init(struct perf_evsel *evsel __maybe_unused) |
38 | { | 42 | { |
39 | return 0; | 43 | return 0; |
@@ -761,6 +765,12 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts) | |||
761 | attr->disabled = 0; | 765 | attr->disabled = 0; |
762 | attr->enable_on_exec = 0; | 766 | attr->enable_on_exec = 0; |
763 | } | 767 | } |
768 | |||
769 | clockid = opts->clockid; | ||
770 | if (opts->use_clockid) { | ||
771 | attr->use_clockid = 1; | ||
772 | attr->clockid = opts->clockid; | ||
773 | } | ||
764 | } | 774 | } |
765 | 775 | ||
766 | static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) | 776 | static int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) |
@@ -1036,7 +1046,6 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp) | |||
1036 | ret += PRINT_ATTR2(exclude_user, exclude_kernel); | 1046 | ret += PRINT_ATTR2(exclude_user, exclude_kernel); |
1037 | ret += PRINT_ATTR2(exclude_hv, exclude_idle); | 1047 | ret += PRINT_ATTR2(exclude_hv, exclude_idle); |
1038 | ret += PRINT_ATTR2(mmap, comm); | 1048 | ret += PRINT_ATTR2(mmap, comm); |
1039 | ret += PRINT_ATTR2(mmap2, comm_exec); | ||
1040 | ret += PRINT_ATTR2(freq, inherit_stat); | 1049 | ret += PRINT_ATTR2(freq, inherit_stat); |
1041 | ret += PRINT_ATTR2(enable_on_exec, task); | 1050 | ret += PRINT_ATTR2(enable_on_exec, task); |
1042 | ret += PRINT_ATTR2(watermark, precise_ip); | 1051 | ret += PRINT_ATTR2(watermark, precise_ip); |
@@ -1044,6 +1053,9 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp) | |||
1044 | ret += PRINT_ATTR2(exclude_host, exclude_guest); | 1053 | ret += PRINT_ATTR2(exclude_host, exclude_guest); |
1045 | ret += PRINT_ATTR2N("excl.callchain_kern", exclude_callchain_kernel, | 1054 | ret += PRINT_ATTR2N("excl.callchain_kern", exclude_callchain_kernel, |
1046 | "excl.callchain_user", exclude_callchain_user); | 1055 | "excl.callchain_user", exclude_callchain_user); |
1056 | ret += PRINT_ATTR2(mmap2, comm_exec); | ||
1057 | ret += __PRINT_ATTR("%u",,use_clockid); | ||
1058 | |||
1047 | 1059 | ||
1048 | ret += PRINT_ATTR_U32(wakeup_events); | 1060 | ret += PRINT_ATTR_U32(wakeup_events); |
1049 | ret += PRINT_ATTR_U32(wakeup_watermark); | 1061 | ret += PRINT_ATTR_U32(wakeup_watermark); |
@@ -1055,6 +1067,7 @@ static size_t perf_event_attr__fprintf(struct perf_event_attr *attr, FILE *fp) | |||
1055 | ret += PRINT_ATTR_X64(branch_sample_type); | 1067 | ret += PRINT_ATTR_X64(branch_sample_type); |
1056 | ret += PRINT_ATTR_X64(sample_regs_user); | 1068 | ret += PRINT_ATTR_X64(sample_regs_user); |
1057 | ret += PRINT_ATTR_U32(sample_stack_user); | 1069 | ret += PRINT_ATTR_U32(sample_stack_user); |
1070 | ret += PRINT_ATTR_U32(clockid); | ||
1058 | ret += PRINT_ATTR_X64(sample_regs_intr); | 1071 | ret += PRINT_ATTR_X64(sample_regs_intr); |
1059 | 1072 | ||
1060 | ret += fprintf(fp, "%.60s\n", graph_dotted_line); | 1073 | ret += fprintf(fp, "%.60s\n", graph_dotted_line); |
@@ -1085,6 +1098,12 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | |||
1085 | } | 1098 | } |
1086 | 1099 | ||
1087 | fallback_missing_features: | 1100 | fallback_missing_features: |
1101 | if (perf_missing_features.clockid_wrong) | ||
1102 | evsel->attr.clockid = CLOCK_MONOTONIC; /* should always work */ | ||
1103 | if (perf_missing_features.clockid) { | ||
1104 | evsel->attr.use_clockid = 0; | ||
1105 | evsel->attr.clockid = 0; | ||
1106 | } | ||
1088 | if (perf_missing_features.cloexec) | 1107 | if (perf_missing_features.cloexec) |
1089 | flags &= ~(unsigned long)PERF_FLAG_FD_CLOEXEC; | 1108 | flags &= ~(unsigned long)PERF_FLAG_FD_CLOEXEC; |
1090 | if (perf_missing_features.mmap2) | 1109 | if (perf_missing_features.mmap2) |
@@ -1122,6 +1141,17 @@ retry_open: | |||
1122 | goto try_fallback; | 1141 | goto try_fallback; |
1123 | } | 1142 | } |
1124 | set_rlimit = NO_CHANGE; | 1143 | set_rlimit = NO_CHANGE; |
1144 | |||
1145 | /* | ||
1146 | * If we succeeded but had to kill clockid, fail and | ||
1147 | * have perf_evsel__open_strerror() print us a nice | ||
1148 | * error. | ||
1149 | */ | ||
1150 | if (perf_missing_features.clockid || | ||
1151 | perf_missing_features.clockid_wrong) { | ||
1152 | err = -EINVAL; | ||
1153 | goto out_close; | ||
1154 | } | ||
1125 | } | 1155 | } |
1126 | } | 1156 | } |
1127 | 1157 | ||
@@ -1155,7 +1185,17 @@ try_fallback: | |||
1155 | if (err != -EINVAL || cpu > 0 || thread > 0) | 1185 | if (err != -EINVAL || cpu > 0 || thread > 0) |
1156 | goto out_close; | 1186 | goto out_close; |
1157 | 1187 | ||
1158 | if (!perf_missing_features.cloexec && (flags & PERF_FLAG_FD_CLOEXEC)) { | 1188 | /* |
1189 | * Must probe features in the order they were added to the | ||
1190 | * perf_event_attr interface. | ||
1191 | */ | ||
1192 | if (!perf_missing_features.clockid_wrong && evsel->attr.use_clockid) { | ||
1193 | perf_missing_features.clockid_wrong = true; | ||
1194 | goto fallback_missing_features; | ||
1195 | } else if (!perf_missing_features.clockid && evsel->attr.use_clockid) { | ||
1196 | perf_missing_features.clockid = true; | ||
1197 | goto fallback_missing_features; | ||
1198 | } else if (!perf_missing_features.cloexec && (flags & PERF_FLAG_FD_CLOEXEC)) { | ||
1159 | perf_missing_features.cloexec = true; | 1199 | perf_missing_features.cloexec = true; |
1160 | goto fallback_missing_features; | 1200 | goto fallback_missing_features; |
1161 | } else if (!perf_missing_features.mmap2 && evsel->attr.mmap2) { | 1201 | } else if (!perf_missing_features.mmap2 && evsel->attr.mmap2) { |
@@ -2063,9 +2103,7 @@ int perf_evsel__fprintf(struct perf_evsel *evsel, | |||
2063 | if_print(exclude_hv); | 2103 | if_print(exclude_hv); |
2064 | if_print(exclude_idle); | 2104 | if_print(exclude_idle); |
2065 | if_print(mmap); | 2105 | if_print(mmap); |
2066 | if_print(mmap2); | ||
2067 | if_print(comm); | 2106 | if_print(comm); |
2068 | if_print(comm_exec); | ||
2069 | if_print(freq); | 2107 | if_print(freq); |
2070 | if_print(inherit_stat); | 2108 | if_print(inherit_stat); |
2071 | if_print(enable_on_exec); | 2109 | if_print(enable_on_exec); |
@@ -2076,10 +2114,17 @@ int perf_evsel__fprintf(struct perf_evsel *evsel, | |||
2076 | if_print(sample_id_all); | 2114 | if_print(sample_id_all); |
2077 | if_print(exclude_host); | 2115 | if_print(exclude_host); |
2078 | if_print(exclude_guest); | 2116 | if_print(exclude_guest); |
2117 | if_print(mmap2); | ||
2118 | if_print(comm_exec); | ||
2119 | if_print(use_clockid); | ||
2079 | if_print(__reserved_1); | 2120 | if_print(__reserved_1); |
2080 | if_print(wakeup_events); | 2121 | if_print(wakeup_events); |
2081 | if_print(bp_type); | 2122 | if_print(bp_type); |
2082 | if_print(branch_sample_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); | ||
2083 | } | 2128 | } |
2084 | out: | 2129 | out: |
2085 | fputc('\n', fp); | 2130 | fputc('\n', fp); |
@@ -2158,6 +2203,12 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, | |||
2158 | "The PMU counters are busy/taken by another profiler.\n" | 2203 | "The PMU counters are busy/taken by another profiler.\n" |
2159 | "We found oprofile daemon running, please stop it and try again."); | 2204 | "We found oprofile daemon running, please stop it and try again."); |
2160 | break; | 2205 | break; |
2206 | case EINVAL: | ||
2207 | if (perf_missing_features.clockid) | ||
2208 | return scnprintf(msg, size, "clockid feature not supported."); | ||
2209 | if (perf_missing_features.clockid_wrong) | ||
2210 | return scnprintf(msg, size, "wrong clockid (%d).", clockid); | ||
2211 | break; | ||
2161 | default: | 2212 | default: |
2162 | break; | 2213 | break; |
2163 | } | 2214 | } |