tools/perf/arch/arm64/util/arm-spe.c

Source file repositories/reference/linux-study-clean/tools/perf/arch/arm64/util/arm-spe.c

File Facts

System
Linux kernel
Corpus path
tools/perf/arch/arm64/util/arm-spe.c
Extension
.c
Size
18521 bytes
Lines
695
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

tracking_evsel->core.attr.context_switch = 1;
	}

	return 0;
}

static int arm_spe_recording_options(struct auxtrace_record *itr,
				     struct evlist *evlist,
				     struct record_opts *opts)
{
	struct arm_spe_recording *sper =
			container_of(itr, struct arm_spe_recording, itr);
	struct evsel *evsel, *tmp;
	struct perf_cpu_map *cpus = evlist->core.user_requested_cpus;
	bool discard = false;
	int err;
	u64 discard_bit;

	sper->evlist = evlist;

	evlist__for_each_entry(evlist, evsel) {
		if (evsel__is_aux_event(evsel)) {
			if (!strstarts(evsel->pmu->name, ARM_SPE_PMU_NAME)) {
				pr_err("Found unexpected auxtrace event: %s\n",
				       evsel->pmu->name);
				return -EINVAL;
			}
			opts->full_auxtrace = true;

			if (opts->user_freq != UINT_MAX ||
			    arm_spe_is_set_freq(evsel)) {
				pr_err("Arm SPE: Frequency is not supported. "
				       "Set period with -c option or PMU parameter (-e %s/period=NUM/).\n",
				       evsel->pmu->name);
				return -EINVAL;
			}
		}
	}

	if (!opts->full_auxtrace)
		return 0;

	evlist__for_each_entry_safe(evlist, tmp, evsel) {
		if (evsel__is_aux_event(evsel)) {
			arm_spe_setup_evsel(evsel, cpus);
			if (!evsel__get_config_val(evsel, "discard", &discard_bit))
				discard = !!discard_bit;
		}
	}

	if (discard)
		return 0;

	err = arm_spe_setup_aux_buffer(opts);
	if (err)
		return err;

	return arm_spe_setup_tracking_event(evlist, opts);
}

static int arm_spe_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused,
					 struct record_opts *opts,
					 const char *str)
{
	unsigned long long snapshot_size = 0;
	char *endptr;

	if (str) {
		snapshot_size = strtoull(str, &endptr, 0);
		if (*endptr || snapshot_size > SIZE_MAX)
			return -1;
	}

	opts->auxtrace_snapshot_mode = true;
	opts->auxtrace_snapshot_size = snapshot_size;

	return 0;
}

static int arm_spe_snapshot_start(struct auxtrace_record *itr)
{
	struct arm_spe_recording *ptr =
			container_of(itr, struct arm_spe_recording, itr);
	struct evsel *evsel;
	int ret = -EINVAL;

	evlist__for_each_entry(ptr->evlist, evsel) {
		if (evsel__is_aux_event(evsel)) {
			ret = evsel__disable(evsel);
			if (ret < 0)

Annotation

Implementation Notes