tools/perf/arch/x86/tests/amd-ibs-period.c

Source file repositories/reference/linux-study-clean/tools/perf/arch/x86/tests/amd-ibs-period.c

File Facts

System
Linux kernel
Corpus path
tools/perf/arch/x86/tests/amd-ibs-period.c
Extension
.c
Size
30705 bytes
Lines
1032
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 ibs_configs {
	/* Input */
	unsigned long config;

	/* Expected output */
	unsigned long period;
	int fd;
};

/*
 * Somehow first Fetch event with sample period = 0x10 causes 0
 * samples. So start with large period and decrease it gradually.
 */
struct ibs_configs fetch_configs[] = {
	{ .config =  0xffff, .period = 0xffff0, .fd = FD_SUCCESS },
	{ .config =  0x1000, .period = 0x10000, .fd = FD_SUCCESS },
	{ .config =    0xff, .period =   0xff0, .fd = FD_SUCCESS },
	{ .config =     0x1, .period =    0x10, .fd = FD_SUCCESS },
	{ .config =     0x0, .period =      -1, .fd = FD_ERROR   },
	{ .config = 0x10000, .period =      -1, .fd = FD_ERROR   },
};

struct ibs_configs op_configs[] = {
	{ .config =        0x0, .period =        -1, .fd = FD_ERROR   },
	{ .config =        0x1, .period =        -1, .fd = FD_ERROR   },
	{ .config =        0x8, .period =        -1, .fd = FD_ERROR   },
	{ .config =        0x9, .period =      0x90, .fd = FD_SUCCESS },
	{ .config =        0xf, .period =      0xf0, .fd = FD_SUCCESS },
	{ .config =     0x1000, .period =   0x10000, .fd = FD_SUCCESS },
	{ .config =     0xffff, .period =   0xffff0, .fd = FD_SUCCESS },
	{ .config =    0x10000, .period =        -1, .fd = FD_ERROR   },
	{ .config =   0x100000, .period =  0x100000, .fd = FD_SUCCESS },
	{ .config =   0xf00000, .period =  0xf00000, .fd = FD_SUCCESS },
	{ .config =   0xf0ffff, .period =  0xfffff0, .fd = FD_SUCCESS },
	{ .config =  0x1f0ffff, .period = 0x1fffff0, .fd = FD_SUCCESS },
	{ .config =  0x7f0ffff, .period = 0x7fffff0, .fd = FD_SUCCESS },
	{ .config =  0x8f0ffff, .period =        -1, .fd = FD_ERROR   },
	{ .config = 0x17f0ffff, .period =        -1, .fd = FD_ERROR   },
};

static int __ibs_config_test(int ibs_type, struct ibs_configs *config, int *nr_samples)
{
	struct perf_event_attr attr;
	int fd, i;
	void *rb;
	int ret = 0;

	if (ibs_type == IBS_FETCH)
		fetch_prepare_attr(&attr, config->config, 0, 0);
	else
		op_prepare_attr(&attr, config->config, 0, 0);

	/* CPU0, All processes */
	fd = perf_event_open(&attr, -1, 0, -1, 0);
	if (config->fd == FD_ERROR) {
		if (fd != -1) {
			close(fd);
			return -1;
		}
		return 0;
	}
	if (fd <= -1)
		return -1;

	rb = mmap(NULL, PERF_MMAP_TOTAL_SIZE, PROT_READ | PROT_WRITE,
		  MAP_SHARED, fd, 0);
	if (rb == MAP_FAILED) {
		pr_debug("mmap() failed. [%m]\n");
		return -1;
	}

	ioctl(fd, PERF_EVENT_IOC_RESET, 0);
	ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);

	i = 5;
	while (i--) {
		dummy_workload_1(1000000);

		ret = rb_drain_samples(rb, config->period, nr_samples,
				       period_equal);
		if (ret)
			break;
	}

	ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
	munmap(rb, PERF_MMAP_TOTAL_SIZE);
	close(fd);
	return ret;
}

Annotation

Implementation Notes