diff options
Diffstat (limited to 'tools/perf/util/evsel.c')
-rw-r--r-- | tools/perf/util/evsel.c | 60 |
1 files changed, 33 insertions, 27 deletions
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 1cad6051d8b0..c26ea82220bd 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -497,7 +497,7 @@ static const char *__evsel__hw_name(u64 config) return "unknown-hardware"; } -static int perf_evsel__add_modifiers(struct evsel *evsel, char *bf, size_t size) +static int evsel__add_modifiers(struct evsel *evsel, char *bf, size_t size) { int colon = 0, r = 0; struct perf_event_attr *attr = &evsel->core.attr; @@ -536,7 +536,7 @@ static int perf_evsel__add_modifiers(struct evsel *evsel, char *bf, size_t size) static int evsel__hw_name(struct evsel *evsel, char *bf, size_t size) { int r = scnprintf(bf, size, "%s", __evsel__hw_name(evsel->core.attr.config)); - return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); + return r + evsel__add_modifiers(evsel, bf + r, size - r); } const char *evsel__sw_names[PERF_COUNT_SW_MAX] = { @@ -562,7 +562,7 @@ static const char *__evsel__sw_name(u64 config) static int evsel__sw_name(struct evsel *evsel, char *bf, size_t size) { int r = scnprintf(bf, size, "%s", __evsel__sw_name(evsel->core.attr.config)); - return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); + return r + evsel__add_modifiers(evsel, bf + r, size - r); } static int __evsel__bp_name(char *bf, size_t size, u64 addr, u64 type) @@ -587,7 +587,7 @@ static int evsel__bp_name(struct evsel *evsel, char *bf, size_t size) { struct perf_event_attr *attr = &evsel->core.attr; int r = __evsel__bp_name(bf, size, attr->bp_addr, attr->bp_type); - return r + perf_evsel__add_modifiers(evsel, bf + r, size - r); + return r + evsel__add_modifiers(evsel, bf + r, size - r); } const char *evsel__hw_cache[PERF_COUNT_HW_CACHE_MAX][EVSEL__MAX_ALIASES] = { @@ -682,13 +682,13 @@ out_err: static int evsel__hw_cache_name(struct evsel *evsel, char *bf, size_t size) { int ret = __evsel__hw_cache_name(evsel->core.attr.config, bf, size); - return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); + return ret + evsel__add_modifiers(evsel, bf + ret, size - ret); } static int evsel__raw_name(struct evsel *evsel, char *bf, size_t size) { int ret = scnprintf(bf, size, "raw 0x%" PRIx64, evsel->core.attr.config); - return ret + perf_evsel__add_modifiers(evsel, bf + ret, size - ret); + return ret + evsel__add_modifiers(evsel, bf + ret, size - ret); } static int evsel__tool_name(char *bf, size_t size) @@ -850,9 +850,7 @@ void evsel__config_callchain(struct evsel *evsel, struct record_opts *opts, return __evsel__config_callchain(evsel, opts, param); } -static void -perf_evsel__reset_callgraph(struct evsel *evsel, - struct callchain_param *param) +static void evsel__reset_callgraph(struct evsel *evsel, struct callchain_param *param) { struct perf_event_attr *attr = &evsel->core.attr; @@ -988,7 +986,7 @@ static void evsel__apply_config_terms(struct evsel *evsel, /* If global callgraph set, clear it */ if (callchain_param.enabled) - perf_evsel__reset_callgraph(evsel, &callchain_param); + evsel__reset_callgraph(evsel, &callchain_param); /* set perf-event callgraph */ if (param.enabled) { @@ -1190,6 +1188,9 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts, evsel__set_sample_bit(evsel, CGROUP); } + if (opts->sample_data_page_size) + evsel__set_sample_bit(evsel, DATA_PAGE_SIZE); + if (opts->record_switch_events) attr->context_switch = track; @@ -1434,9 +1435,7 @@ static int evsel__read_one(struct evsel *evsel, int cpu, int thread) return perf_evsel__read(&evsel->core, cpu, thread, count); } -static void -perf_evsel__set_count(struct evsel *counter, int cpu, int thread, - u64 val, u64 ena, u64 run) +static void evsel__set_count(struct evsel *counter, int cpu, int thread, u64 val, u64 ena, u64 run) { struct perf_counts_values *count; @@ -1449,9 +1448,7 @@ perf_evsel__set_count(struct evsel *counter, int cpu, int thread, perf_counts__set_loaded(counter->counts, cpu, thread, true); } -static int -perf_evsel__process_group_data(struct evsel *leader, - int cpu, int thread, u64 *data) +static int evsel__process_group_data(struct evsel *leader, int cpu, int thread, u64 *data) { u64 read_format = leader->core.attr.read_format; struct sample_read_value *v; @@ -1470,18 +1467,16 @@ perf_evsel__process_group_data(struct evsel *leader, v = (struct sample_read_value *) data; - perf_evsel__set_count(leader, cpu, thread, - v[0].value, ena, run); + evsel__set_count(leader, cpu, thread, v[0].value, ena, run); for (i = 1; i < nr; i++) { struct evsel *counter; - counter = perf_evlist__id2evsel(leader->evlist, v[i].id); + counter = evlist__id2evsel(leader->evlist, v[i].id); if (!counter) return -EINVAL; - perf_evsel__set_count(counter, cpu, thread, - v[i].value, ena, run); + evsel__set_count(counter, cpu, thread, v[i].value, ena, run); } return 0; @@ -1514,7 +1509,7 @@ static int evsel__read_group(struct evsel *leader, int cpu, int thread) if (readn(FD(leader, cpu, thread), data, size) <= 0) return -errno; - return perf_evsel__process_group_data(leader, cpu, thread, data); + return evsel__process_group_data(leader, cpu, thread, data); } int evsel__read_counter(struct evsel *evsel, int cpu, int thread) @@ -1567,9 +1562,7 @@ static int get_group_fd(struct evsel *evsel, int cpu, int thread) return fd; } -static void perf_evsel__remove_fd(struct evsel *pos, - int nr_cpus, int nr_threads, - int thread_idx) +static void evsel__remove_fd(struct evsel *pos, int nr_cpus, int nr_threads, int thread_idx) { for (int cpu = 0; cpu < nr_cpus; cpu++) for (int thread = thread_idx; thread < nr_threads - 1; thread++) @@ -1588,7 +1581,7 @@ static int update_fds(struct evsel *evsel, evlist__for_each_entry(evsel->evlist, pos) { nr_cpus = pos != evsel ? nr_cpus : cpu_idx; - perf_evsel__remove_fd(pos, nr_cpus, nr_threads, thread_idx); + evsel__remove_fd(pos, nr_cpus, nr_threads, thread_idx); /* * Since fds for next evsel has not been created, @@ -1880,7 +1873,12 @@ try_fallback: * Must probe features in the order they were added to the * perf_event_attr interface. */ - if (!perf_missing_features.cgroup && evsel->core.attr.cgroup) { + if (!perf_missing_features.data_page_size && + (evsel->core.attr.sample_type & PERF_SAMPLE_DATA_PAGE_SIZE)) { + perf_missing_features.data_page_size = true; + pr_debug2_peo("Kernel has no PERF_SAMPLE_DATA_PAGE_SIZE support, bailing out\n"); + goto out_close; + } else if (!perf_missing_features.cgroup && evsel->core.attr.cgroup) { perf_missing_features.cgroup = true; pr_debug2_peo("Kernel has no cgroup sampling support, bailing out\n"); goto out_close; @@ -2365,6 +2363,12 @@ int evsel__parse_sample(struct evsel *evsel, union perf_event *event, array++; } + data->data_page_size = 0; + if (type & PERF_SAMPLE_DATA_PAGE_SIZE) { + data->data_page_size = *array; + array++; + } + if (type & PERF_SAMPLE_AUX) { OVERFLOW_CHECK_u64(array); sz = *array++; @@ -2674,6 +2678,8 @@ int evsel__open_strerror(struct evsel *evsel, struct target *target, "We found oprofile daemon running, please stop it and try again."); break; case EINVAL: + if (evsel->core.attr.sample_type & PERF_SAMPLE_DATA_PAGE_SIZE && perf_missing_features.data_page_size) + return scnprintf(msg, size, "Asking for the data page size isn't supported by this kernel."); if (evsel->core.attr.write_backward && perf_missing_features.write_backward) return scnprintf(msg, size, "Reading from overwrite event is not supported by this kernel."); if (perf_missing_features.clockid) |