linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Fenghua Yu <fenghua.yu@intel.com>
To: "Thomas Gleixner" <tglx@linutronix.de>,
	"Ingo Molnar" <mingo@redhat.com>, "H Peter Anvin" <hpa@zytor.com>
Cc: "Ashok Raj" <ashok.raj@intel.com>,
	"Alan Cox" <alan@linux.intel.com>,
	"Ravi V Shankar" <ravi.v.shankar@intel.com>,
	"linux-kernel" <linux-kernel@vger.kernel.org>,
	"x86" <x86@kernel.org>, Fenghua Yu <fenghua.yu@intel.com>
Subject: [RFC PATCH 8/8] selftests/x86: Self test for the APIs in lib_direct_store.h and lib_user_wait.h
Date: Fri, 15 Jun 2018 20:06:15 -0700	[thread overview]
Message-ID: <1529118375-90191-9-git-send-email-fenghua.yu@intel.com> (raw)
In-Reply-To: <1529118375-90191-1-git-send-email-fenghua.yu@intel.com>

The self test checks APIs defined in arch/x86/include/uapi/asm/
lib_direct_store.h and arch/x86/include/uapi/asm/lib_user_wait.h

Limited by testing environment, this test suit only tests simple cases.
More test cases may be added later.

Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
---
 tools/testing/selftests/x86/Makefile             |   5 +-
 tools/testing/selftests/x86/directstore_umwait.c | 202 +++++++++++++++++++++++
 2 files changed, 205 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/x86/directstore_umwait.c

diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile
index 186520198de7..36cf86f3eeae 100644
--- a/tools/testing/selftests/x86/Makefile
+++ b/tools/testing/selftests/x86/Makefile
@@ -12,7 +12,8 @@ CAN_BUILD_WITH_NOPIE := $(shell ./check_cc.sh $(CC) trivial_program.c -no-pie)
 
 TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt test_mremap_vdso \
 			check_initial_reg_state sigreturn iopl mpx-mini-test ioperm \
-			protection_keys test_vdso test_vsyscall mov_ss_trap
+			protection_keys test_vdso test_vsyscall mov_ss_trap \
+			directstore_umwait
 TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \
 			test_FCMOV test_FCOMI test_FISTTP \
 			vdso_restorer
@@ -73,7 +74,7 @@ $(BINARIES_32): $(OUTPUT)/%_32: %.c
 	$(CC) -m32 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -lm
 
 $(BINARIES_64): $(OUTPUT)/%_64: %.c
-	$(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl
+	$(CC) -m64 -o $@ $(CFLAGS) $(EXTRA_CFLAGS) $^ -lrt -ldl -lm
 
 # x86_64 users should be encouraged to install 32-bit libraries
 ifeq ($(CAN_BUILD_I386)$(CAN_BUILD_X86_64),01)
diff --git a/tools/testing/selftests/x86/directstore_umwait.c b/tools/testing/selftests/x86/directstore_umwait.c
new file mode 100644
index 000000000000..d1bb1293d2ad
--- /dev/null
+++ b/tools/testing/selftests/x86/directstore_umwait.c
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * directstore_umwait.c - Test APIs defined in lib_direct_store.h and
+ * lib_user_wait.h
+ *
+ * Copyright (c) 2018 Intel Corporation
+ * Fenghua Yu <fenghua.yu@intel.com>
+ */
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <asm/lib_direct_store.h>
+#include <asm/lib_user_wait.h>
+
+void test_movdiri_32_bit(void)
+{
+	int __attribute((aligned(64))) dst[10];
+	int __attribute((aligned(64))) data;
+
+	if (!movdiri_supported()) {
+		printf("movdiri is not supported\n");
+
+		return;
+	}
+	dst[0] = 0;
+	data = 0x12345670;
+
+	movdiri32(dst, data);
+
+	if (dst[0] == data)
+		printf("movdiri 32-bit test passed\n");
+	else
+		printf("movdiri 32-bit test failed\n");
+}
+
+void test_movdiri_64_bit(void)
+{
+	long __attribute((aligned(64))) dst[10];
+	long __attribute((aligned(64))) data;
+
+	if (!movdiri_supported()) {
+		printf("movdiri is not supported\n");
+
+		return;
+	}
+	dst[0] = 0;
+	data = 0x123456789abcdef0;
+
+	movdiri64(dst, data);
+
+	if (dst[0] == data)
+		printf("movdiri 64-bit test passed\n");
+	else
+		printf("movdiri 64-bit test failed\n");
+}
+
+void test_movdiri(void)
+{
+	test_movdiri_32_bit();
+	test_movdiri_64_bit();
+}
+
+void test_movdir64b(void)
+{
+	char __attribute((aligned(64))) src[1024], dst[1024];
+
+	if (!movdir64b_supported()) {
+		printf("movdir64b is not supported\n");
+
+		return;
+	}
+	memset(src, 0, 1024);
+	memset(dst, 0, 1024);
+	for (int i = 0; i < 1024; i++)
+		dst[i] = i;
+
+	movdir64b(src, dst);
+	if (memcmp(src, dst, 64))
+		printf("movdir64b test failed\n");
+	else
+		printf("movdir64b test passed\n");
+}
+
+void test_timeout(char *test_name, int state, unsigned long timeout_ns,
+		  unsigned long overhead_ns)
+{
+	unsigned long tsc1, tsc2, real_tsc, real_ns, tsc_per_nsec;
+	int ret;
+
+	ret = nsec_to_tsc(1, &tsc_per_nsec);
+	if (ret) {
+		printf("umwait test failed: nsec cannot be coverted to tsc.\n");
+		return;
+	}
+
+	if (waitpkg_supported()) {
+		if (!strcmp(test_name, "umwait")) {
+			tsc1 = rdtsc();
+			umwait(state, timeout_ns);
+			tsc2 = rdtsc();
+		} else {
+			tsc1 = rdtsc();
+			tpause(state, timeout_ns);
+			tsc2 = rdtsc();
+		}
+		real_tsc = tsc2 - tsc1;
+		real_ns = real_tsc / tsc_per_nsec;
+		/* Give enough time for overhead on slow running machine. */
+		if (abs(real_ns - timeout_ns) < overhead_ns) {
+			printf("%s test passed\n", test_name);
+		} else {
+			printf("%s test failed:\n", test_name);
+			printf("real=%luns, expected=%luns. ",
+			       real_ns, timeout_ns);
+			printf("Likely due to slow machine. ");
+			printf("Please adjust overhead_ns or re-run test for a few more times.\n");
+		}
+	} else {
+		printf("%s is not supported\n", test_name);
+	}
+}
+
+void test_tpause_timeout(int state)
+{
+	/*
+	 * Timeout 100usec. Assume overhead of executing umwait is 10usec.
+	 * You can adjust the overhead number based on your machine.
+	 */
+	test_timeout("tpause", state, 100000, 10000);
+}
+
+void test_tpause(void)
+{
+	/* Test timeout in state 0 (C0.2). */
+	test_tpause_timeout(0);
+	/* Test timeout in state 1 (C0.1). */
+	test_tpause_timeout(1);
+	/* More tests ... */
+}
+
+char umonitor_range[1024];
+
+void test_umonitor_only(void)
+{
+	if (waitpkg_supported()) {
+		umonitor(umonitor_range);
+		printf("umonitor test passed\n");
+	} else {
+		printf("waitpkg not supported\n");
+	}
+}
+
+void show_basic_info(void)
+{
+	unsigned long tsc;
+	int ret;
+
+	ret = nsec_to_tsc(1, &tsc);
+	if (ret < 0)
+		printf("not tsc freq CPUID available\n");
+	else
+		printf("1 nsec = %lu tsc\n", tsc);
+}
+
+void test_umonitor(void)
+{
+	test_umonitor_only();
+}
+
+void test_umwait_timeout(int state)
+{
+	/*
+	 * Timeout 100usec. Overhead of executing umwait assumes 90usec.
+	 * You can adjust the overhead number based on your machine.
+	 */
+	test_timeout("umwait", state, 100000, 90000);
+}
+
+void test_umwait(void)
+{
+	/* Test timeout in state 0 (C0.2). */
+	test_umwait_timeout(0);
+	/* Test timeout in state 1 (C0.1). */
+	test_umwait_timeout(1);
+	/* More tests ... */
+}
+
+int main(void)
+{
+	show_basic_info();
+	test_movdiri();
+	test_movdir64b();
+	test_tpause();
+	test_umonitor();
+	test_umwait();
+
+	return 0;
+}
-- 
2.5.0


      parent reply	other threads:[~2018-06-16  3:08 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-16  3:06 [RFC PATCH 0/8] x86: Enable a few new instructions Fenghua Yu
2018-06-16  3:06 ` [RFC PATCH 1/8] x86/cpufeatures: Enumerate MOVDIRI instruction Fenghua Yu
2018-06-19  8:57   ` Thomas Gleixner
2018-06-19 21:36     ` Fenghua Yu
2018-06-19 22:32       ` Thomas Gleixner
2018-06-19 22:35         ` Fenghua Yu
2018-06-25 16:13       ` David Laight
2018-06-16  3:06 ` [RFC PATCH 2/8] x86/cpufeatures: Enumerate MOVDIR64B instruction Fenghua Yu
2018-06-16  3:06 ` [RFC PATCH 3/8] x86/cpufeatures: Enumerate UMONITOR, UMWAIT, and TPAUSE instructions Fenghua Yu
2018-06-16  3:06 ` [RFC PATCH 4/8] cpuidle: Set up maximum umwait time and umwait states Fenghua Yu
2018-06-19  9:03   ` Thomas Gleixner
2018-06-19 15:46     ` Fenghua Yu
2018-06-16  3:06 ` [RFC PATCH 5/8] x86/umwait.c: Add sysfs interface to show tsc_khz Fenghua Yu
2018-06-19  9:08   ` Thomas Gleixner
2018-06-19 15:11     ` Fenghua Yu
2018-06-16  3:06 ` [RFC PATCH 6/8] x86/lib_direct_store.h: Add APIs for direct store instructions Fenghua Yu
2018-06-19  8:47   ` Thomas Gleixner
2018-06-16  3:06 ` [RFC PATCH 7/8] x86/lib_user_wait.h: Add APIs for user wait instructions Fenghua Yu
2018-06-19  9:12   ` Thomas Gleixner
2018-06-19 22:27     ` Fenghua Yu
2018-06-19 22:34       ` Thomas Gleixner
2018-06-19 22:36         ` Fenghua Yu
2018-06-16  3:06 ` Fenghua Yu [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1529118375-90191-9-git-send-email-fenghua.yu@intel.com \
    --to=fenghua.yu@intel.com \
    --cc=alan@linux.intel.com \
    --cc=ashok.raj@intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=ravi.v.shankar@intel.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).