tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c
Extension
.c
Size
13443 bytes
Lines
554
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

if (header->type == PERF_RECORD_SAMPLE) {
			*size = (header->size - sizeof(header));
			if (!sample_count)
				return sample_buff + page_size + data_tail;
			data_tail += *size;
			*sample_count += 1;
		} else {
			*size = (header->size - sizeof(header));
			if ((metadata_page->data_tail + *size) > metadata_page->data_head)
				data_tail = metadata_page->data_head;
			else
				data_tail += *size;
		}
		header = (struct perf_event_header *)((void *)header + header->size);
	}
	return NULL;
}

int collect_samples(void *sample_buff)
{
	u64 sample_count;
	size_t size = 0;

	__event_read_samples(sample_buff, &size, &sample_count);
	return sample_count;
}

static void *perf_read_first_sample(void *sample_buff, size_t *size)
{
	return __event_read_samples(sample_buff, size, NULL);
}

u64 *get_intr_regs(struct event *event, void *sample_buff)
{
	u64 type = event->attr.sample_type;
	u64 *intr_regs;
	size_t size = 0;

	if ((type ^ (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_BRANCH_STACK)) &&
			(type  ^ PERF_SAMPLE_REGS_INTR))
		return NULL;

	intr_regs = (u64 *)perf_read_first_sample(sample_buff, &size);
	if (!intr_regs)
		return NULL;

	if (type & PERF_SAMPLE_BRANCH_STACK) {
		/*
		 * PERF_RECORD_SAMPLE and PERF_SAMPLE_BRANCH_STACK:
		 * struct {
		 *     struct perf_event_header hdr;
		 *     u64 number_of_branches;
		 *     struct perf_branch_entry[number_of_branches];
		 *     u64 data[];
		 * };
		 * struct perf_branch_entry {
		 *     u64	from;
		 *     u64	to;
		 *     u64	misc;
		 * };
		 */
		intr_regs += ((*intr_regs) * 3) + 1;
	}

	/*
	 * First entry in the sample buffer used to specify
	 * PERF_SAMPLE_REGS_ABI_64, skip perf regs abi to access
	 * interrupt registers.
	 */
	++intr_regs;

	return intr_regs;
}

static const int __perf_reg_mask(const char *register_name)
{
	if (!strcmp(register_name, "R0"))
		return 0;
	else if (!strcmp(register_name, "R1"))
		return 1;
	else if (!strcmp(register_name, "R2"))
		return 2;
	else if (!strcmp(register_name, "R3"))
		return 3;
	else if (!strcmp(register_name, "R4"))
		return 4;
	else if (!strcmp(register_name, "R5"))
		return 5;
	else if (!strcmp(register_name, "R6"))
		return 6;

Annotation

Implementation Notes