tools/perf/tests/event_groups.c

Source file repositories/reference/linux-study-clean/tools/perf/tests/event_groups.c

File Facts

System
Linux kernel
Corpus path
tools/perf/tests/event_groups.c
Extension
.c
Size
4253 bytes
Lines
158
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 (!strcmp(uncore_pmus[i].name, pmu->name)) {
				pr_debug("Using %s for uncore pmu event\n", pmu->name);
				types[2] = pmu->type;
				configs[2] = uncore_pmus[i].config;
				/*
				 * Check if the chosen uncore pmu event can be
				 * used in the test. For example, incase of accessing
				 * hv_24x7 pmu counters, partition should have
				 * additional permissions. If not, event open will
				 * fail. So check if the event open succeeds
				 * before proceeding.
				 */
				fd = event_open(types[2], configs[2], -1);
				if (fd < 0)
					return -1;
				close(fd);
				return 0;
			}
		}
	}
	return -1;
}

static int run_test(int i, int j, int k)
{
	int erroneous = ((((1 << i) | (1 << j) | (1 << k)) & 5) == 5);
	int group_fd, sibling_fd1, sibling_fd2;

	group_fd = event_open(types[i], configs[i], -1);
	if (group_fd == -1)
		return -1;

	sibling_fd1 = event_open(types[j], configs[j], group_fd);
	if (sibling_fd1 == -1) {
		close(group_fd);
		return erroneous ? 0 : -1;
	}

	/*
	 * if all three events (leader and two sibling events)
	 * are hardware events, use instructions as one of the
	 * sibling event. There is event constraint in powerpc that
	 * events using same counter cannot be programmed in a group.
	 * Since PERF_COUNT_HW_INSTRUCTIONS is a generic hardware
	 * event and present in all platforms, lets use that.
	 */
	if (!i && !j && !k)
		sibling_fd2 = event_open(types[k], configs_hw[k], group_fd);
	else
		sibling_fd2 = event_open(types[k], configs[k], group_fd);
	if (sibling_fd2 == -1) {
		close(sibling_fd1);
		close(group_fd);
		return erroneous ? 0 : -1;
	}

	close(sibling_fd2);
	close(sibling_fd1);
	close(group_fd);
	return erroneous ? -1 : 0;
}

static int test__event_groups(struct test_suite *text __maybe_unused, int subtest __maybe_unused)
{
	int i, j, k;
	int ret;
	int r;

	ret = setup_uncore_event();
	if (ret || types[2] == -1)
		return TEST_SKIP;

	ret = TEST_OK;
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 3; j++) {
			for (k = 0; k < 3; k++) {
				r = run_test(i, j, k);
				if (r)
					ret = TEST_FAIL;

				/*
				 * For all three events as HW events, second sibling
				 * event is picked from configs_hw. So print accordingly
				 */
				if (!i && !j && !k)
					pr_debug("0x%x 0x%lx, 0x%x 0x%lx, 0x%x 0x%lx: %s\n",
						 types[i], configs[i], types[j], configs[j],
						 types[k], configs_hw[k], r ? "Fail" : "Pass");
				else
					pr_debug("0x%x 0x%lx, 0x%x 0x%lx, 0x%x 0x%lx: %s\n",

Annotation

Implementation Notes