tools/testing/selftests/powerpc/ptrace/perf-hwbreak.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/powerpc/ptrace/perf-hwbreak.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/powerpc/ptrace/perf-hwbreak.c
Extension
.c
Size
21133 bytes
Lines
896
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 (fd[i] < 0) {
			perror("perf_systemwide_event_open");
			close_fds(fd, i);
			ret = fd[i];
			goto done;
		}
		i++;
	}

	if (i < nprocs) {
		printf("Error: Number of online cpus reduced since start of test: %d < %d\n", i, nprocs);
		close_fds(fd, i);
		ret = -1;
	}

done:
	CPU_FREE(mask);
	return ret;
}

static inline bool breakpoint_test(int len)
{
	int fd;

	/* bp_addr can point anywhere but needs to be aligned */
	fd = perf_process_event_open(HW_BREAKPOINT_R, (__u64)(&fd) & 0xfffffffffffff800, len);
	if (fd < 0)
		return false;
	close(fd);
	return true;
}

static inline bool perf_breakpoint_supported(void)
{
	return breakpoint_test(4);
}

static inline bool dawr_supported(void)
{
	return breakpoint_test(DAWR_LENGTH_MAX);
}

static int runtestsingle(int readwriteflag, int exclude_user, int arraytest)
{
	int i,j;
	size_t res;
	unsigned long long breaks, needed;
	int readint;
	int readintarraybig[2*DAWR_LENGTH_MAX/sizeof(int)];
	int *readintalign;
	volatile int *ptr;
	int break_fd;
	int loop_num = MAX_LOOPS - (rand() % 100); /* provide some variability */
	volatile int *k;
	__u64 len;

	/* align to 0x400 boundary as required by DAWR */
	readintalign = (int *)(((unsigned long)readintarraybig + 0x7ff) &
			       0xfffffffffffff800);

	ptr = &readint;
	if (arraytest)
		ptr = &readintalign[0];

	len = arraytest ? DAWR_LENGTH_MAX : sizeof(int);
	break_fd = perf_process_event_open_exclude_user(readwriteflag, (__u64)ptr,
							len, exclude_user);
	if (break_fd < 0) {
		perror("perf_process_event_open_exclude_user");
		exit(1);
	}

	/* start counters */
	ioctl(break_fd, PERF_EVENT_IOC_ENABLE);

	/* Test a bunch of reads and writes */
	k = &readint;
	for (i = 0; i < loop_num; i++) {
		if (arraytest)
			k = &(readintalign[i % (DAWR_LENGTH_MAX/sizeof(int))]);

		j = *k;
		*k = j;
	}

	/* stop counters */
	ioctl(break_fd, PERF_EVENT_IOC_DISABLE);

	/* read and check counters */
	res = read(break_fd, &breaks, sizeof(unsigned long long));

Annotation

Implementation Notes