tools/perf/arch/arm64/util/hisi-ptt.c

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

File Facts

System
Linux kernel
Corpus path
tools/perf/arch/arm64/util/hisi-ptt.c
Extension
.c
Size
4743 bytes
Lines
189
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

struct hisi_ptt_recording {
	struct auxtrace_record	itr;
	struct perf_pmu *hisi_ptt_pmu;
	struct evlist *evlist;
};

static size_t
hisi_ptt_info_priv_size(struct auxtrace_record *itr __maybe_unused,
			struct evlist *evlist __maybe_unused)
{
	return HISI_PTT_AUXTRACE_PRIV_SIZE;
}

static int hisi_ptt_info_fill(struct auxtrace_record *itr,
			      struct perf_session *session,
			      struct perf_record_auxtrace_info *auxtrace_info,
			      size_t priv_size)
{
	struct hisi_ptt_recording *pttr =
			container_of(itr, struct hisi_ptt_recording, itr);
	struct perf_pmu *hisi_ptt_pmu = pttr->hisi_ptt_pmu;

	if (priv_size != HISI_PTT_AUXTRACE_PRIV_SIZE)
		return -EINVAL;

	if (!session->evlist->core.nr_mmaps)
		return -EINVAL;

	auxtrace_info->type = PERF_AUXTRACE_HISI_PTT;
	auxtrace_info->priv[0] = hisi_ptt_pmu->type;

	return 0;
}

static int hisi_ptt_set_auxtrace_mmap_page(struct record_opts *opts)
{
	bool privileged = perf_event_paranoid_check(-1);

	if (!opts->full_auxtrace)
		return 0;

	if (opts->full_auxtrace && !opts->auxtrace_mmap_pages) {
		if (privileged) {
			opts->auxtrace_mmap_pages = MiB(16) / page_size;
		} else {
			opts->auxtrace_mmap_pages = KiB(128) / page_size;
			if (opts->mmap_pages == UINT_MAX)
				opts->mmap_pages = KiB(256) / page_size;
		}
	}

	/* Validate auxtrace_mmap_pages */
	if (opts->auxtrace_mmap_pages) {
		size_t sz = opts->auxtrace_mmap_pages * (size_t)page_size;
		size_t min_sz = KiB(8);

		if (sz < min_sz || !is_power_of_2(sz)) {
			pr_err("Invalid mmap size for HISI PTT: must be at least %zuKiB and a power of 2\n",
			       min_sz / 1024);
			return -EINVAL;
		}
	}

	return 0;
}

static int hisi_ptt_recording_options(struct auxtrace_record *itr,
				      struct evlist *evlist,
				      struct record_opts *opts)
{
	struct hisi_ptt_recording *pttr =
			container_of(itr, struct hisi_ptt_recording, itr);
	struct perf_pmu *hisi_ptt_pmu = pttr->hisi_ptt_pmu;
	struct evsel *evsel, *hisi_ptt_evsel = NULL;
	struct evsel *tracking_evsel;
	int err;

	pttr->evlist = evlist;
	evlist__for_each_entry(evlist, evsel) {
		if (evsel->core.attr.type == hisi_ptt_pmu->type) {
			if (hisi_ptt_evsel) {
				pr_err("There may be only one " HISI_PTT_PMU_NAME "x event\n");
				return -EINVAL;
			}
			evsel->core.attr.freq = 0;
			evsel->core.attr.sample_period = 1;
			evsel->needs_auxtrace_mmap = true;
			hisi_ptt_evsel = evsel;
			opts->full_auxtrace = true;
		}

Annotation

Implementation Notes