Lines Matching +full:t +full:- +full:head
1 // SPDX-License-Identifier: GPL-2.0
4 * Copyright (c) 2017-2018, Arm Ltd.
27 #include "../../../util/arm-spe.h"
48 list_for_each_entry(term, &evsel->config_terms, list) { in arm_spe_is_set_freq()
49 if (term->type == EVSEL__CONFIG_TERM_FREQ) in arm_spe_is_set_freq()
62 struct perf_cpu_map *event_cpus = evlist->core.user_requested_cpus; in arm_spe_find_cpus()
108 return -ENOMEM; in arm_spe_save_cpu_header()
113 data[ARM_SPE_CPU_NR_PARAMS] = ARM_SPE_CPU_PRIV_MAX - ARM_SPE_CPU_MIDR; in arm_spe_save_cpu_header()
117 if (perf_cpu_map__has(sper->arm_spe_pmu->cpus, cpu)) in arm_spe_save_cpu_header()
118 pmu = sper->arm_spe_pmu; in arm_spe_save_cpu_header()
126 data[ARM_SPE_CPU_PMU_TYPE] = pmu->type; in arm_spe_save_cpu_header()
150 struct perf_pmu *arm_spe_pmu = sper->arm_spe_pmu; in arm_spe_info_fill()
155 if (priv_size != arm_spe_info_priv_size(itr, session->evlist)) in arm_spe_info_fill()
156 return -EINVAL; in arm_spe_info_fill()
158 if (!session->evlist->core.nr_mmaps) in arm_spe_info_fill()
159 return -EINVAL; in arm_spe_info_fill()
161 cpu_map = arm_spe_find_cpus(session->evlist); in arm_spe_info_fill()
163 return -EINVAL; in arm_spe_info_fill()
165 auxtrace_info->type = PERF_AUXTRACE_ARM_SPE; in arm_spe_info_fill()
166 auxtrace_info->priv[ARM_SPE_HEADER_VERSION] = ARM_SPE_HEADER_CURRENT_VERSION; in arm_spe_info_fill()
167 auxtrace_info->priv[ARM_SPE_HEADER_SIZE] = in arm_spe_info_fill()
168 ARM_SPE_AUXTRACE_PRIV_MAX - ARM_SPE_HEADER_VERSION; in arm_spe_info_fill()
169 auxtrace_info->priv[ARM_SPE_PMU_TYPE_V2] = arm_spe_pmu->type; in arm_spe_info_fill()
170 auxtrace_info->priv[ARM_SPE_CPUS_NUM] = perf_cpu_map__nr(cpu_map); in arm_spe_info_fill()
175 data = &auxtrace_info->priv[offset]; in arm_spe_info_fill()
204 * No size were given to '-S' or '-m,', so go with the default in arm_spe_snapshot_resolve_auxtrace_defaults()
206 if (!opts->auxtrace_snapshot_size && !opts->auxtrace_mmap_pages) { in arm_spe_snapshot_resolve_auxtrace_defaults()
208 opts->auxtrace_mmap_pages = MiB(4) / page_size; in arm_spe_snapshot_resolve_auxtrace_defaults()
210 opts->auxtrace_mmap_pages = KiB(128) / page_size; in arm_spe_snapshot_resolve_auxtrace_defaults()
211 if (opts->mmap_pages == UINT_MAX) in arm_spe_snapshot_resolve_auxtrace_defaults()
212 opts->mmap_pages = KiB(256) / page_size; in arm_spe_snapshot_resolve_auxtrace_defaults()
214 } else if (!opts->auxtrace_mmap_pages && !privileged && opts->mmap_pages == UINT_MAX) { in arm_spe_snapshot_resolve_auxtrace_defaults()
215 opts->mmap_pages = KiB(256) / page_size; in arm_spe_snapshot_resolve_auxtrace_defaults()
219 * '-m,xyz' was specified but no snapshot size, so make the snapshot size as big as the in arm_spe_snapshot_resolve_auxtrace_defaults()
222 if (!opts->auxtrace_snapshot_size) in arm_spe_snapshot_resolve_auxtrace_defaults()
223 opts->auxtrace_snapshot_size = opts->auxtrace_mmap_pages * (size_t)page_size; in arm_spe_snapshot_resolve_auxtrace_defaults()
226 * '-Sxyz' was specified but no auxtrace mmap area, so make the auxtrace mmap area big in arm_spe_snapshot_resolve_auxtrace_defaults()
229 if (!opts->auxtrace_mmap_pages) { in arm_spe_snapshot_resolve_auxtrace_defaults()
230 size_t sz = opts->auxtrace_snapshot_size; in arm_spe_snapshot_resolve_auxtrace_defaults()
233 opts->auxtrace_mmap_pages = roundup_pow_of_two(sz); in arm_spe_snapshot_resolve_auxtrace_defaults()
245 * If kernel driver doesn't advertise a minimum, in arm_spe_pmu__sample_period()
250 pr_debug("arm_spe driver doesn't advertise a min. interval. Using 4096\n"); in arm_spe_pmu__sample_period()
260 evsel->core.attr.freq = 0; in arm_spe_setup_evsel()
261 evsel->core.attr.sample_period = arm_spe_pmu__sample_period(evsel->pmu); in arm_spe_setup_evsel()
262 evsel->needs_auxtrace_mmap = true; in arm_spe_setup_evsel()
268 evlist__to_front(evsel->evlist, evsel); in arm_spe_setup_evsel()
271 * In the case of per-cpu mmaps, sample CPU for AUX event; in arm_spe_setup_evsel()
276 evsel__set_config_if_unset(evsel->pmu, evsel, "ts_enable", 1); in arm_spe_setup_evsel()
290 bit = perf_pmu__format_bits(evsel->pmu, "pa_enable"); in arm_spe_setup_evsel()
291 if (evsel->core.attr.config & bit) in arm_spe_setup_evsel()
297 bool privileged = perf_event_paranoid_check(-1); in arm_spe_setup_aux_buffer()
302 if (opts->auxtrace_snapshot_mode) { in arm_spe_setup_aux_buffer()
304 * Command arguments '-Sxyz' and/or '-m,xyz' are missing, so fill those in with in arm_spe_setup_aux_buffer()
307 if (!opts->auxtrace_snapshot_size || !opts->auxtrace_mmap_pages) in arm_spe_setup_aux_buffer()
311 * Snapshot size can't be bigger than the auxtrace area. in arm_spe_setup_aux_buffer()
313 if (opts->auxtrace_snapshot_size > opts->auxtrace_mmap_pages * (size_t)page_size) { in arm_spe_setup_aux_buffer()
315 opts->auxtrace_snapshot_size, in arm_spe_setup_aux_buffer()
316 opts->auxtrace_mmap_pages * (size_t)page_size); in arm_spe_setup_aux_buffer()
317 return -EINVAL; in arm_spe_setup_aux_buffer()
321 * Something went wrong somewhere - this shouldn't happen. in arm_spe_setup_aux_buffer()
323 if (!opts->auxtrace_snapshot_size || !opts->auxtrace_mmap_pages) { in arm_spe_setup_aux_buffer()
325 return -EINVAL; in arm_spe_setup_aux_buffer()
329 opts->auxtrace_snapshot_size); in arm_spe_setup_aux_buffer()
332 /* We are in full trace mode but '-m,xyz' wasn't specified */ in arm_spe_setup_aux_buffer()
333 if (!opts->auxtrace_mmap_pages) { in arm_spe_setup_aux_buffer()
335 opts->auxtrace_mmap_pages = MiB(4) / page_size; in arm_spe_setup_aux_buffer()
337 opts->auxtrace_mmap_pages = KiB(128) / page_size; in arm_spe_setup_aux_buffer()
338 if (opts->mmap_pages == UINT_MAX) in arm_spe_setup_aux_buffer()
339 opts->mmap_pages = KiB(256) / page_size; in arm_spe_setup_aux_buffer()
344 if (opts->auxtrace_mmap_pages) { in arm_spe_setup_aux_buffer()
345 size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size; in arm_spe_setup_aux_buffer()
351 return -EINVAL; in arm_spe_setup_aux_buffer()
363 struct perf_cpu_map *cpus = evlist->core.user_requested_cpus; in arm_spe_setup_tracking_event()
373 tracking_evsel->core.attr.freq = 0; in arm_spe_setup_tracking_event()
374 tracking_evsel->core.attr.sample_period = 1; in arm_spe_setup_tracking_event()
376 /* In per-cpu case, always need the time of mmap events etc */ in arm_spe_setup_tracking_event()
383 tracking_evsel->core.attr.context_switch = 1; in arm_spe_setup_tracking_event()
396 struct perf_cpu_map *cpus = evlist->core.user_requested_cpus; in arm_spe_recording_options()
400 sper->evlist = evlist; in arm_spe_recording_options()
404 if (!strstarts(evsel->pmu->name, ARM_SPE_PMU_NAME)) { in arm_spe_recording_options()
406 evsel->pmu->name); in arm_spe_recording_options()
407 return -EINVAL; in arm_spe_recording_options()
409 opts->full_auxtrace = true; in arm_spe_recording_options()
411 if (opts->user_freq != UINT_MAX || in arm_spe_recording_options()
414 "Set period with -c option or PMU parameter (-e %s/period=NUM/).\n", in arm_spe_recording_options()
415 evsel->pmu->name); in arm_spe_recording_options()
416 return -EINVAL; in arm_spe_recording_options()
421 if (!opts->full_auxtrace) in arm_spe_recording_options()
427 if (evsel->core.attr.config & in arm_spe_recording_options()
428 perf_pmu__format_bits(evsel->pmu, "discard")) in arm_spe_recording_options()
453 return -1; in arm_spe_parse_snapshot_options()
456 opts->auxtrace_snapshot_mode = true; in arm_spe_parse_snapshot_options()
457 opts->auxtrace_snapshot_size = snapshot_size; in arm_spe_parse_snapshot_options()
467 int ret = -EINVAL; in arm_spe_snapshot_start()
469 evlist__for_each_entry(ptr->evlist, evsel) { in arm_spe_snapshot_start()
484 int ret = -EINVAL; in arm_spe_snapshot_finish()
486 evlist__for_each_entry(ptr->evlist, evsel) { in arm_spe_snapshot_finish()
499 int cnt = ptr->wrapped_cnt, new_cnt, i; in arm_spe_alloc_wrapped_array()
508 * Make ptr->wrapped as big as idx. in arm_spe_alloc_wrapped_array()
515 wrapped = reallocarray(ptr->wrapped, new_cnt, sizeof(bool)); in arm_spe_alloc_wrapped_array()
517 return -ENOMEM; in arm_spe_alloc_wrapped_array()
525 ptr->wrapped_cnt = new_cnt; in arm_spe_alloc_wrapped_array()
526 ptr->wrapped = wrapped; in arm_spe_alloc_wrapped_array()
532 size_t buffer_size, u64 head) in arm_spe_buffer_has_wrapped() argument
539 * Defensively handle the case where head might be continually increasing - if its value is in arm_spe_buffer_has_wrapped()
541 * wrapped around. Otherwise, continue to detect if head might have wrapped. in arm_spe_buffer_has_wrapped()
543 if (head >= buffer_size) in arm_spe_buffer_has_wrapped()
549 watermark = buf_size - 512; in arm_spe_buffer_has_wrapped()
552 * The value of head is somewhere within the size of the ring buffer. This can be that there in arm_spe_buffer_has_wrapped()
553 * hasn't been enough data to fill the ring buffer yet or the trace time was so long that in arm_spe_buffer_has_wrapped()
554 * head has numerically wrapped around. To find we need to check if we have data at the in arm_spe_buffer_has_wrapped()
560 * head is less than 512 byte from the end of the ring buffer. in arm_spe_buffer_has_wrapped()
562 if (head > watermark) in arm_spe_buffer_has_wrapped()
563 watermark = head; in arm_spe_buffer_has_wrapped()
572 * If we find trace data at the end of the ring buffer, head has been there and has in arm_spe_buffer_has_wrapped()
584 u64 *head, u64 *old) in arm_spe_find_snapshot() argument
595 if (idx >= ptr->wrapped_cnt) { in arm_spe_find_snapshot()
602 * Check to see if *head has wrapped around. If it hasn't only the in arm_spe_find_snapshot()
603 * amount of data between *head and *old is snapshot'ed to avoid in arm_spe_find_snapshot()
604 * bloating the perf.data file with zeros. But as soon as *head has in arm_spe_find_snapshot()
607 wrapped = ptr->wrapped[idx]; in arm_spe_find_snapshot()
608 if (!wrapped && arm_spe_buffer_has_wrapped(data, mm->len, *head)) { in arm_spe_find_snapshot()
610 ptr->wrapped[idx] = true; in arm_spe_find_snapshot()
613 pr_debug3("%s: mmap index %d old head %zu new head %zu size %zu\n", in arm_spe_find_snapshot()
614 __func__, idx, (size_t)*old, (size_t)*head, mm->len); in arm_spe_find_snapshot()
617 * No wrap has occurred, we can just use *head and *old. in arm_spe_find_snapshot()
623 * *head has wrapped around - adjust *head and *old to pickup the in arm_spe_find_snapshot()
626 if (*head >= mm->len) { in arm_spe_find_snapshot()
627 *old = *head - mm->len; in arm_spe_find_snapshot()
629 *head += mm->len; in arm_spe_find_snapshot()
630 *old = *head - mm->len; in arm_spe_find_snapshot()
650 zfree(&sper->wrapped); in arm_spe_recording_free()
660 *err = -ENODEV; in arm_spe_recording_init()
666 *err = -ENOMEM; in arm_spe_recording_init()
670 sper->arm_spe_pmu = arm_spe_pmu; in arm_spe_recording_init()
671 sper->itr.snapshot_start = arm_spe_snapshot_start; in arm_spe_recording_init()
672 sper->itr.snapshot_finish = arm_spe_snapshot_finish; in arm_spe_recording_init()
673 sper->itr.find_snapshot = arm_spe_find_snapshot; in arm_spe_recording_init()
674 sper->itr.parse_snapshot_options = arm_spe_parse_snapshot_options; in arm_spe_recording_init()
675 sper->itr.recording_options = arm_spe_recording_options; in arm_spe_recording_init()
676 sper->itr.info_priv_size = arm_spe_info_priv_size; in arm_spe_recording_init()
677 sper->itr.info_fill = arm_spe_info_fill; in arm_spe_recording_init()
678 sper->itr.free = arm_spe_recording_free; in arm_spe_recording_init()
679 sper->itr.reference = arm_spe_reference; in arm_spe_recording_init()
680 sper->itr.read_finish = auxtrace_record__read_finish; in arm_spe_recording_init()
681 sper->itr.alignment = 0; in arm_spe_recording_init()
684 return &sper->itr; in arm_spe_recording_init()
690 attr->sample_period = arm_spe_pmu__sample_period(arm_spe_pmu); in arm_spe_pmu_default_config()